Skip to content

Update order quotes sdk function to return pre-formetted strings#2001

Merged
findolor merged 9 commits intomainfrom
2025-07-16-order-quote
Jul 17, 2025
Merged

Update order quotes sdk function to return pre-formetted strings#2001
findolor merged 9 commits intomainfrom
2025-07-16-order-quote

Conversation

@findolor
Copy link
Copy Markdown
Collaborator

@findolor findolor commented Jul 16, 2025

Motivation

See issue: #1968

This PR updates the return type of the order quotes logic to include pre-formatted strings.

Solution

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

    • Added ability to fetch and display user token balances directly from vaults, with both raw and formatted values.
    • Enhanced order quote data to include formatted string outputs and additional computed fields for clearer presentation.
  • Refactor

    • Updated components and services to use new balance retrieval and formatted quote structures, removing direct blockchain interaction logic from UI components.
    • Centralized balance fetching logic within the vault abstraction for improved maintainability.
  • Bug Fixes

    • Improved error handling and validation when fetching user balances and displaying order quotes.
  • Tests

    • Expanded and updated tests to cover new balance and quote formats, ensuring accurate display and behavior across components.

@findolor findolor requested review from 0xgleb and hardyjosh July 16, 2025 11:27
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jul 16, 2025

Walkthrough

This set of changes introduces structured, formatted balance and quote data retrieval across the Rust backend and TypeScript/Svelte frontend. New methods and types allow querying ERC-20 token balances and order quotes, returning both raw and formatted values. UI components and tests are refactored to use these new abstractions, removing direct blockchain calls and formatting logic from the frontend.

Changes

Files/Areas Change Summary
crates/common/src/erc20.rs Added async method to query ERC-20 token balance (get_account_balance) and supporting test.
crates/common/src/raindex_client/order_quotes.rs Introduced RaindexOrderQuote and RaindexOrderQuoteValue structs with formatted fields; refactored quote retrieval to use these types; updated tests.
crates/common/src/raindex_client/vaults.rs Added AccountBalance struct and methods to fetch and format owner's token balance; exposed WASM binding; added test.
packages/orderbook/test/js_api/raindexClient.test.ts Updated order quote tests to check formatted fields; added test for vault account balance retrieval.
packages/ui-components/src/__tests__/TanstackOrderQuote.test.ts Adjusted mocked order quote data and assertions to use formatted string fields instead of raw hex.
packages/ui-components/src/lib/components/detail/TanstackOrderQuote.svelte Refactored to use RaindexOrderQuote and preformatted string fields for display; removed manual formatting.
packages/ui-components/src/lib/services/historicalOrderCharts.ts Replaced manual formatting with use of preformatted string fields in historical order chart data processing and tests.
packages/webapp/src/__tests__/DepositModal.test.ts,
packages/webapp/src/__tests__/WithdrawModal.test.ts
Removed direct blockchain mocks; now mock getOwnerBalance on vault; removed chain switch error test.
packages/webapp/src/lib/components/DepositModal.svelte,
packages/webapp/src/lib/components/WithdrawModal.svelte
Refactored to use vault.getOwnerBalance() for balance retrieval; updated UI and validation to use AccountBalance object.
tauri-app/src/lib/components/ModalVaultDeposit.svelte Updated to use AccountBalance object for user balance; removed manual formatting and direct blockchain call.

Sequence Diagram(s)

sequenceDiagram
    participant UI
    participant Vault
    participant ERC20
    participant Blockchain

    UI->>Vault: getOwnerBalance()
    Vault->>ERC20: get_account_balance(owner_address)
    ERC20->>Blockchain: balanceOf(owner_address)
    Blockchain-->>ERC20: U256 balance
    ERC20-->>Vault: U256 balance
    Vault-->>UI: AccountBalance { balance, formatted_balance }
Loading
sequenceDiagram
    participant UI
    participant RaindexOrder
    participant Backend

    UI->>RaindexOrder: get_quotes()
    RaindexOrder->>Backend: fetch batch order quotes
    Backend-->>RaindexOrder: raw quote data
    RaindexOrder-->>UI: RaindexOrderQuote[] (with formatted fields)
Loading

Suggested labels

rust

Suggested reviewers

  • hardyjosh

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Clippy (1.86.0)
Updating crates.io index
Updating git repository `https://github.com/rainlanguage/rain.wasm`

error: failed to get wasm-bindgen-utils as a dependency of package rain_orderbook_bindings v0.0.0-alpha.0 (/crates/bindings)

Caused by:
failed to load source for dependency wasm-bindgen-utils

Caused by:
Unable to update https://github.com/rainlanguage/rain.wasm?rev=06990d85a0b7c55378a1c8cca4dd9e2bc34a596a#06990d85

Caused by:
failed to create directory /usr/local/git/db/rain.wasm-45eded9facc525c2

Caused by:
Permission denied (os error 13)


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1ec3655 and 35204a5.

📒 Files selected for processing (1)
  • crates/common/src/raindex_client/vaults.rs (4 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#0
File: :0-0
Timestamp: 2025-05-21T23:34:42.328Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, the PR size report must use the format:
TOTAL:number
ADDITIONS:number
DELETIONS:number
with no extra text, formatting blocks, or explanations, and must still exclude lock files and reassess after each new commit.
Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#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
PR: rainlanguage/rain.orderbook#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).
Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#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
PR: rainlanguage/rain.orderbook#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
PR: rainlanguage/rain.orderbook#0
File: :0-0
Timestamp: 2025-05-21T22:47:21.927Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, the PR size report must always be placed at the very beginning of any comment, before any learning used section or other content.
Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#0
File: :0-0
Timestamp: 2025-05-21T22:47:21.927Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, the PR size report must always be placed at the very beginning of any comment, before any learning used section or other content.
Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#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
PR: rainlanguage/rain.orderbook#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
PR: rainlanguage/rain.orderbook#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
PR: rainlanguage/rain.orderbook#2000
File: crates/common/src/raindex_client/vaults.rs:183-183
Timestamp: 2025-07-16T10:40:05.656Z
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.
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1994
File: crates/common/src/raindex_client/vaults.rs:59-59
Timestamp: 2025-07-16T05:52:05.538Z
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.
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1956
File: crates/common/src/fuzz/mod.rs:64-64
Timestamp: 2025-07-04T09:02:57.301Z
Learning: In rainlanguage/rain.orderbook, user findolor prefers to limit type consistency changes to only the parts directly related to the current work scope. For example, when updating chain_id fields from u64 to u32 in fuzz-related code, unrelated files like tauri-app wallet commands can remain as u64 if they serve different purposes and aren't part of the current changes.
Learnt from: findolor
PR: rainlanguage/rain.orderbook#2001
File: crates/common/src/raindex_client/order_quotes.rs:62-69
Timestamp: 2025-07-16T14:33:13.409Z
Learning: In the rainlanguage/rain.orderbook codebase, findolor considers hardcoded decimal values (18 and 36) in order quote formatting logic to be acceptable for their use case, even when dynamic token decimals could theoretically provide more accurate formatting for different tokens.
Learnt from: hardingjam
PR: rainlanguage/rain.orderbook#1496
File: packages/webapp/src/lib/components/DepositOrWithdrawModal.svelte:164-164
Timestamp: 2025-03-22T21:11:34.405Z
Learning: The refactoring to replace signerAddress with account from useAccount hook is being done in stages - shared UI components first (PR #1496), with webapp-specific components to be handled in a separate future PR.
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.
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.
Learnt from: hardingjam
PR: rainlanguage/rain.orderbook#1896
File: tauri-app/src/lib/services/executeWalletConnectOrder.ts:41-45
Timestamp: 2025-05-27T12:01:51.647Z
Learning: In the tauri-app codebase, the formatEthersTransactionErrorFn function already handles error formatting appropriately for toast messages in executeWalletConnectOrder, so additional granular error handling based on error types is not needed.
Learnt from: hardingjam
PR: rainlanguage/rain.orderbook#1504
File: tauri-app/src/routes/orders/[network]-[orderHash]/+page.svelte:33-37
Timestamp: 2025-04-08T16:35:15.127Z
Learning: In the Rain OrderBook project, the onDeposit and onWithdraw functions in page components are kept simple (just calling modal handlers and revalidating queries) because error handling for deposit and withdraw actions (including user cancellations and failed transactions) is handled within the modal components themselves.
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1925
File: packages/ui-components/src/lib/components/deployment/DeploymentSteps.svelte:87-104
Timestamp: 2025-06-18T16:42:40.608Z
Learning: In the orderbook UI components, changing deployments or networks requires page navigation, which automatically remounts components and refreshes data like available tokens. No additional refresh logic is needed for deployment/network changes.
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1925
File: crates/settings/src/remote_tokens.rs:44-62
Timestamp: 2025-07-11T08:45:43.961Z
Learning: findolor prefers to avoid performance micro-optimizations like changing `.values()` to `.into_values()` in HashMap iterations in the rainlanguage/rain.orderbook codebase, even when they would eliminate unnecessary cloning.
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1903
File: crates/js_api/src/subgraph/vault.rs:129-138
Timestamp: 2025-06-17T16:33:58.549Z
Learning: findolor prefers downstream error handling over early validation checks for empty RPC lists in vault functions, allowing errors to bubble up from provider creation logic naturally.
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1916
File: packages/webapp/src/routes/+layout.ts:26-26
Timestamp: 2025-06-10T12:01:07.418Z
Learning: The user findolor prefers to keep string concatenation using the plus operator over template literals in the rainlanguage/rain.orderbook project, even when static analysis tools suggest the change.
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1975
File: crates/js_api/src/config.rs:44-45
Timestamp: 2025-07-09T07:42:48.458Z
Learning: User findolor prefers to defer code improvements and refactoring suggestions to future PRs when they are not directly related to the current PR's scope, even when the suggestions are valid improvements.
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1947
File: crates/common/src/raindex_client/orders.rs:462-1643
Timestamp: 2025-06-24T08:45:10.971Z
Learning: User findolor prefers to keep tests simple and avoid refactoring for maintainability when the code is stable and viewed as "one time thing" that won't require frequent changes.
crates/common/src/raindex_client/vaults.rs (35)

<retrieved_learning>
Learnt from: findolor
PR: #2000
File: crates/common/src/raindex_client/vaults.rs:183-183
Timestamp: 2025-07-16T10:40:05.656Z
Learning: In the rainlanguage/rain.orderbook codebase, user findolor considers breaking changes from Option to U256 for required fields like decimals in RaindexVaultToken to be acceptable and safe, even when they affect multiple usage sites across the codebase.
</retrieved_learning>

<retrieved_learning>
Learnt from: findolor
PR: #1994
File: crates/common/src/raindex_client/vaults.rs:59-59
Timestamp: 2025-07-16T05:52:05.538Z
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.
</retrieved_learning>

<retrieved_learning>
Learnt from: findolor
PR: #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.
</retrieved_learning>

<retrieved_learning>
Learnt from: findolor
PR: #1744
File: packages/webapp/src/lib/components/DepositOrWithdrawModal.svelte:73-76
Timestamp: 2025-05-09T05:30:02.520Z
Learning: In Rain.orderbook, VaultCalldataResult is a wrapper type that contains both error and value properties. When using this in the DepositOrWithdrawModal component, only the inner value field is passed to the handleTransaction function, not the complete wrapper.
</retrieved_learning>

<retrieved_learning>
Learnt from: brusherru
PR: #1957
File: packages/ui-components/src/lib/components/tables/VaultsListTable.svelte:60-60
Timestamp: 2025-06-27T17:34:15.825Z
Learning: In the VaultsListTable.svelte component, the activeAccounts store is redundant in query keys when the owners variable (derived from activeAccountsItems) is already included, as owners is what's actually used in the query function while activeAccounts is just a transformed version of the same data.
</retrieved_learning>

<retrieved_learning>
Learnt from: findolor
PR: #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.
</retrieved_learning>

<retrieved_learning>
Learnt from: findolor
PR: #1874
File: tauri-app/src-tauri/src/transaction_status.rs:69-127
Timestamp: 2025-05-27T06:16:35.738Z
Learning: In tauri-app/src-tauri/src/transaction_status.rs, directly accessing internal RwLock state in tests using notice.0.read().unwrap() is acceptable and does not require encapsulation through public getter methods.
</retrieved_learning>

<retrieved_learning>
Learnt from: findolor
PR: #2001
File: crates/common/src/raindex_client/vaults.rs:0-0
Timestamp: 2025-07-16T14:33:45.855Z
Learning: In the rainlanguage/rain.orderbook codebase, findolor considers using Address::random() in tests to be acceptable when the mock server doesn't validate the address parameter and returns a fixed response, making the test deterministic regardless of the address value used.
</retrieved_learning>

<retrieved_learning>
Learnt from: findolor
PR: #1903
File: crates/settings/src/yaml/orderbook.rs:371-377
Timestamp: 2025-06-17T16:21:24.384Z
Learning: In crates/settings/src/yaml/orderbook.rs tests, the user findolor considers RPC ordering in Vec assertions to be intentional and not a test brittleness issue. The ordering of RPCs in tests should be preserved as specified.
</retrieved_learning>

<retrieved_learning>
Learnt from: 0xgleb
PR: #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.
</retrieved_learning>

<retrieved_learning>
Learnt from: findolor
PR: #1882
File: packages/webapp/src/lib/services/handleVaultDeposit.ts:96-125
Timestamp: 2025-06-07T09:07:53.733Z
Learning: In the vault deposit flow, vault.token.address is already validated before reaching the approval transaction creation, so casting it to Hex type is safe and doesn't require additional validation.
</retrieved_learning>

<retrieved_learning>
Learnt from: findolor
PR: #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.
</retrieved_learning>

<retrieved_learning>
Learnt from: 0xgleb
PR: #1713
File: crates/settings/src/remote/chains/mod.rs:43-226
Timestamp: 2025-05-13T20:06:22.602Z
Learning: When writing tests for collections of complex objects in Rust, prefer item-by-item comparison over direct vector comparison to get more specific error messages that pinpoint exactly which item and field has a mismatch.
</retrieved_learning>

<retrieved_learning>
Learnt from: thedavidmeister
PR: #1926
File: test/concrete/ob/OrderBook.clear.zeroAmount.t.sol:24-32
Timestamp: 2025-06-16T10:49:47.770Z
Learning: LibTestAddOrder.conformConfig() in test/util/lib/LibTestAddOrder.sol automatically constrains OrderConfigV3 to prevent common test failures by ensuring validInputs[0].token != validOutputs[0].token, setting them to address(0) and address(1) respectively if they're equal. This prevents TokenSelfTrade errors in fuzz tests.
</retrieved_learning>

<retrieved_learning>
Learnt from: findolor
PR: #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> type expected by RaindexOrder::try_from_sg_order() method.
</retrieved_learning>

<retrieved_learning>
Learnt from: findolor
PR: #1858
File: crates/subgraph/src/cynic_client.rs:27-29
Timestamp: 2025-05-19T12:25:02.658Z
Learning: In the Rain Orderbook codebase, when passing a URL from self.get_base_url() to reqwest::Client::post(), the .clone() is necessary because get_base_url() returns a reference (&Url), but an owned Url is needed for the reqwest client in the async context to avoid lifetime issues.
</retrieved_learning>

<retrieved_learning>
Learnt from: findolor
PR: #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.
</retrieved_learning>

<retrieved_learning>
Learnt from: hardingjam
PR: #1496
File: packages/webapp/src/lib/components/DepositOrWithdrawModal.svelte:164-164
Timestamp: 2025-03-22T21:11:34.405Z
Learning: The refactoring to replace signerAddress with account from useAccount hook is being done in stages - shared UI components first (PR #1496), with webapp-specific components to be handled in a separate future PR.
</retrieved_learning>

<retrieved_learning>
Learnt from: findolor
PR: #1903
File: crates/common/src/deposit.rs:63-64
Timestamp: 2025-06-17T16:54:43.176Z
Learning: In the rain.orderbook codebase, the maintainer findolor prefers to keep the current implementation that clones the rpcs vector when calling ReadableClient::new_from_urls rather than optimizing it to avoid the clone or adding early validation for empty rpcs. Performance micro-optimizations like avoiding vector clones in this context are not a priority.
</retrieved_learning>

<retrieved_learning>
Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#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.
</retrieved_learning>

<retrieved_learning>
Learnt from: findolor
PR: #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.
</retrieved_learning>

<retrieved_learning>
Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#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.
</retrieved_learning>

<retrieved_learning>
Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#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.
</retrieved_learning>

<retrieved_learning>
Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#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.
</retrieved_learning>

<retrieved_learning>
Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#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.
</retrieved_learning>

<retrieved_learning>
Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#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.
</retrieved_learning>

<retrieved_learning>
Learnt from: hardingjam
PR: #1504
File: tauri-app/src/routes/orders/[network]-[orderHash]/+page.svelte:33-37
Timestamp: 2025-04-08T16:35:15.127Z
Learning: In the Rain OrderBook project, the onDeposit and onWithdraw functions in page components are kept simple (just calling modal handlers and revalidating queries) because error handling for deposit and withdraw actions (including user cancellations and failed transactions) is handled within the modal components themselves.
</retrieved_learning>

<retrieved_learning>
Learnt from: findolor
PR: #1956
File: crates/common/src/raindex_client/orders.rs:609-609
Timestamp: 2025-07-04T10:27:22.544Z
Learning: In the rainlanguage/rain.orderbook codebase, user findolor prefers not to implement overflow protection for trades count casting (usize to u16) at this time, considering it unnecessary for the current scope since the practical risk of orders having 65,535+ trades is extremely low.
</retrieved_learning>

<retrieved_learning>
Learnt from: findolor
PR: #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.
</retrieved_learning>

<retrieved_learning>
Learnt from: findolor
PR: #1872
File: packages/webapp/src/tests/handleVaultDeposit.test.ts:20-53
Timestamp: 2025-06-07T05:19:46.330Z
Learning: In the rain.orderbook codebase, simple wrapper/adapter functions that just delegate to other functions (like handleVaultDeposit) don't need extensive edge case testing for missing parameters or error handling - the current test coverage focusing on core functionality is sufficient.
</retrieved_learning>

<retrieved_learning>
Learnt from: findolor
PR: #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.
</retrieved_learning>

<retrieved_learning>
Learnt from: findolor
PR: #1646
File: crates/settings/src/scenario.rs:1-1
Timestamp: 2025-04-10T11:08:33.383Z
Learning: Wildcard imports (using *) are acceptable in the rain.orderbook codebase, as per the author's preference.
</retrieved_learning>

<retrieved_learning>
Learnt from: hardingjam
PR: #1559
File: packages/ui-components/src/tests/OrderOrVaultHash.test.ts:94-94
Timestamp: 2025-04-04T11:25:21.518Z
Learning: In the rain.orderbook project, minimal test fixtures are preferred over complete mocks that implement the entire interface. Type casting (e.g., as unknown as SgVault) is an acceptable approach to maintain both minimal fixtures and TypeScript type compatibility.
</retrieved_learning>

<retrieved_learning>
Learnt from: 0xgleb
PR: #1844
File: tauri-app/src-tauri/src/commands/wallet.rs:27-28
Timestamp: 2025-05-16T17:24:34.724Z
Learning: In Rust projects, dependencies listed in the [dependencies] section of Cargo.toml are available for both application code and tests. The tokio crate with the "full" feature set includes the "test" feature needed for #[tokio::test] to work properly.
</retrieved_learning>

<retrieved_learning>
Learnt from: hardingjam
PR: #1494
File: packages/ui-components/src/tests/WalletProvider.test.ts:18-28
Timestamp: 2025-03-24T12:27:07.862Z
Learning: In the WalletProvider tests, verifying that setAccountContext is called with the correct store is sufficient. Additional testing of Svelte's store implementation (like subscribing to verify the store value) is unnecessary as it would just be testing the framework itself.
</retrieved_learning>

🔇 Additional comments (5)
crates/common/src/raindex_client/vaults.rs (5)

4-4: Import addition looks good.

The ERC20 import is necessary for the new balance fetching functionality and follows the existing import patterns.


157-165: Well-designed AccountBalance struct.

The struct properly encapsulates both raw and formatted balance data with appropriate serialization and WASM traits, following the existing codebase patterns.


483-513: WASM binding implementation is correct.

The method properly retrieves the owner's balance, formats it using the token's decimals, and returns a structured AccountBalance object. The documentation is comprehensive and includes helpful examples.


516-526: Balance retrieval implementation is sound.

The method correctly creates an ERC20 instance with the necessary RPC URLs and token address, then delegates to the ERC20's get_account_balance method. Error handling is appropriate and consistent with the codebase patterns.


2302-2348: Test implementation is comprehensive.

The test properly mocks both subgraph and RPC responses, verifies the balance retrieval functionality, and uses Address::random() appropriately since the mock server returns a fixed response regardless of the address parameter.

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jul 16, 2025

Walkthrough

The changes introduce a new abstraction for fetching ERC20 account balances via the RaindexVaultToken type, which now holds a reference to the RaindexClient for RPC access. A new AccountBalance struct provides both raw and formatted balance values. The order quote API is enriched with formatted and derived fields, and all related conversion and test code is updated. UI components and tests are refactored to use the new balance-fetching abstraction, removing direct on-chain calls and formatting logic from the frontend.

Changes

File(s) Change Summary
crates/common/src/erc20.rs Added async get_account_balance method to ERC20 for querying token balances. Added related test.
crates/common/src/raindex_client/order_quotes.rs Introduced RaindexOrderQuote/RaindexOrderQuoteValue structs with formatted and derived fields. Updated get_quotes to return enriched types. Adjusted tests.
crates/common/src/raindex_client/orders.rs
crates/common/src/raindex_client/trades.rs
Updated conversion functions to pass Arc<RwLock<RaindexClient>> for context in vault-related conversions. Adjusted method signatures and call sites.
crates/common/src/raindex_client/vaults.rs Added AccountBalance struct and async balance query methods to RaindexVaultToken. Refactored token/vault conversion functions to require client reference. Updated related methods and tests.
packages/orderbook/test/js_api/raindexClient.test.ts Added/updated tests for formatted quote fields and token account balance retrieval via new abstraction.
packages/ui-components/src/__tests__/TanstackOrderQuote.test.ts Updated test data and assertions to use formatted quote fields instead of raw hex values.
packages/ui-components/src/lib/components/detail/TanstackOrderQuote.svelte Refactored to use preformatted quote fields in rendering, removing inline formatting logic.
packages/ui-components/src/lib/services/historicalOrderCharts.ts Removed manual formatting; now uses preformatted string values for amounts/ratios in chart data. Updated test data accordingly.
packages/webapp/src/__tests__/DepositModal.test.ts
packages/webapp/src/__tests__/WithdrawModal.test.ts
Refactored tests to mock getAccountBalance on token abstraction, removing direct contract/chain mocks. Adjusted assertions and removed chain switch failure tests.
packages/webapp/src/lib/components/DepositModal.svelte
packages/webapp/src/lib/components/WithdrawModal.svelte
Replaced direct contract reads and formatting with calls to vault.token.getAccountBalance. Simplified error handling and UI logic to use AccountBalance.
tauri-app/src/lib/components/ModalVaultDeposit.svelte Switched to using AccountBalance for user balance, removed manual formatting and direct contract reads. Updated UI and validation logic.

Sequence Diagram(s)

sequenceDiagram
    participant UI
    participant RaindexVaultToken
    participant RaindexClient
    participant ERC20
    participant EthereumRPC

    UI->>RaindexVaultToken: getAccountBalance(account)
    RaindexVaultToken->>RaindexClient: get_rpc_urls()
    RaindexVaultToken->>ERC20: new(contract_address, rpc_urls)
    RaindexVaultToken->>ERC20: get_account_balance(account)
    ERC20->>EthereumRPC: balanceOf(account)
    EthereumRPC-->>ERC20: balance (U256)
    ERC20-->>RaindexVaultToken: balance (U256)
    RaindexVaultToken-->>UI: AccountBalance { balance, formatted_balance }
Loading
sequenceDiagram
    participant UI
    participant RaindexOrder
    participant RaindexClient
    participant OrderbookQuoteAPI

    UI->>RaindexOrder: get_quotes()
    RaindexOrder->>RaindexClient: fetch_batch_order_quotes()
    RaindexClient->>OrderbookQuoteAPI: getBatchOrderQuotes()
    OrderbookQuoteAPI-->>RaindexClient: BatchOrderQuotesResponse[]
    RaindexClient-->>RaindexOrder: BatchOrderQuotesResponse[]
    RaindexOrder->>RaindexOrder: convert to RaindexOrderQuote (add formatted fields)
    RaindexOrder-->>UI: RaindexOrderQuote[]
Loading

Suggested labels

rust

Suggested reviewers

  • 0xgleb
  • hardyjosh

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

npm error Exit handler never called!
npm error This is an error with npm itself. Please report this error at:
npm error https://github.com/npm/cli/issues
npm error A complete log of this run can be found in: /.npm/_logs/2025-07-16T11_30_00_638Z-debug-0.log

🔧 Clippy (1.86.0)
Updating crates.io index
Updating git repository `https://github.com/rainlanguage/rain.wasm`

error: failed to get wasm-bindgen-utils as a dependency of package rain_orderbook_bindings v0.0.0-alpha.0 (/crates/bindings)

Caused by:
failed to load source for dependency wasm-bindgen-utils

Caused by:
Unable to update https://github.com/rainlanguage/rain.wasm?rev=06990d85a0b7c55378a1c8cca4dd9e2bc34a596a#06990d85

Caused by:
failed to create directory /usr/local/git/db/rain.wasm-45eded9facc525c2

Caused by:
Permission denied (os error 13)

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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

Comment on lines 18 to 21
value: Math.abs(
Number(
formatUnits(
BigInt(d.inputVaultBalanceChange.amount),
Number(d.inputVaultBalanceChange.token.decimals ?? 0)
)
) /
Number(
formatUnits(
BigInt(d.outputVaultBalanceChange.amount),
Number(d.outputVaultBalanceChange.token.decimals ?? 0)
)
)
Number(d.inputVaultBalanceChange.formattedAmount) /
Number(d.outputVaultBalanceChange.formattedAmount)
),
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot Jul 16, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue

Potential precision loss when converting formatted strings to numbers

Converting formatted decimal strings to JavaScript Number type can lead to precision loss for large values. Consider using a decimal arithmetic library like decimal.js for accurate calculations.

-		value: Math.abs(
-			Number(d.inputVaultBalanceChange.formattedAmount) /
-				Number(d.outputVaultBalanceChange.formattedAmount)
-		),
+		value: Math.abs(
+			parseFloat(d.inputVaultBalanceChange.formattedAmount) /
+				parseFloat(d.outputVaultBalanceChange.formattedAmount)
+		),

Alternatively, if high precision is required:

import { Decimal } from 'decimal.js';
// ...
value: new Decimal(d.inputVaultBalanceChange.formattedAmount)
	.div(d.outputVaultBalanceChange.formattedAmount)
	.abs()
	.toNumber(),
🤖 Prompt for AI Agents
In packages/ui-components/src/lib/services/historicalOrderCharts.ts around lines
18 to 21, the code converts formatted decimal strings to JavaScript Number,
which can cause precision loss for large values. To fix this, import a decimal
arithmetic library like decimal.js, then replace the Number conversions with
Decimal instances and perform the division and absolute value operations using
Decimal methods. Finally, convert the result back to a Number if needed using
toNumber().

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 fine and working as expected

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 Thanks for the clarification! I understand that the current implementation with Number() conversion is working as expected for your use case. I'll note this preference for future reference.


✏️ Learnings added
Learnt from: findolor
PR: rainlanguage/rain.orderbook#2001
File: packages/ui-components/src/lib/services/historicalOrderCharts.ts:18-21
Timestamp: 2025-07-16T14:33:03.414Z
Learning: User findolor is comfortable with potential precision loss when converting formatted decimal strings to JavaScript Number type in historicalOrderCharts.ts, preferring the simpler implementation over using decimal arithmetic libraries like decimal.js.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
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.

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.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#2000
File: crates/common/src/raindex_client/vaults.rs:183-183
Timestamp: 2025-07-16T10:40:05.656Z
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.

Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#0
File: :0-0
Timestamp: 2025-05-21T23:09:27.578Z
Learning: For PR #1884 in rainlanguage/rain.orderbook repository, I must always reassess the PR size after each new commit, calculating the total changes up to the very latest commit and ensuring accuracy of the report. The calculation must exclude lock files (package-lock.json, yarn.lock, pnpm-lock.yaml, cargo.lock) and report in the exact format "TOTAL=number\nADDITIONS=number\nDELETIONS=number".

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1744
File: packages/webapp/src/lib/components/DepositOrWithdrawModal.svelte:73-76
Timestamp: 2025-05-09T05:30:02.520Z
Learning: In Rain.orderbook, `VaultCalldataResult` is a wrapper type that contains both `error` and `value` properties. When using this in the `DepositOrWithdrawModal` component, only the inner `value` field is passed to the `handleTransaction` function, not the complete wrapper.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1916
File: packages/webapp/src/routes/+layout.ts:26-26
Timestamp: 2025-06-10T12:01:07.418Z
Learning: The user findolor prefers to keep string concatenation using the plus operator over template literals in the rainlanguage/rain.orderbook project, even when static analysis tools suggest the change.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1994
File: crates/common/src/raindex_client/vaults.rs:59-59
Timestamp: 2025-07-16T05:52:05.538Z
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.

Learnt from: hardingjam
PR: rainlanguage/rain.orderbook#1896
File: tauri-app/src/lib/services/executeWalletConnectOrder.ts:41-45
Timestamp: 2025-05-27T12:01:51.647Z
Learning: In the tauri-app codebase, the formatEthersTransactionErrorFn function already handles error formatting appropriately for toast messages in executeWalletConnectOrder, so additional granular error handling based on error types is not needed.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1971
File: packages/orderbook/package.json:45-46
Timestamp: 2025-07-09T18:31:46.308Z
Learning: In the rain.orderbook project, maintainer findolor prefers to keep TypeDoc dependencies with caret version ranges (e.g., "^0.28.7") rather than pinning to exact versions, even when this might cause unstable HTML output and noisy diffs in generated documentation.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1956
File: crates/common/src/fuzz/mod.rs:64-64
Timestamp: 2025-07-04T09:02:57.301Z
Learning: In rainlanguage/rain.orderbook, user findolor prefers to limit type consistency changes to only the parts directly related to the current work scope. For example, when updating chain_id fields from u64 to u32 in fuzz-related code, unrelated files like tauri-app wallet commands can remain as u64 if they serve different purposes and aren't part of the current changes.

Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#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).

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.

Learnt from: hardingjam
PR: rainlanguage/rain.orderbook#1870
File: packages/webapp/src/lib/components/WithdrawModal.svelte:31-31
Timestamp: 2025-05-20T12:03:18.032Z
Learning: The VaultActionArgs type no longer contains an action property after refactoring the deposit/withdraw modals into separate components.

Learnt from: hardingjam
PR: rainlanguage/rain.orderbook#1559
File: packages/ui-components/src/__tests__/OrderOrVaultHash.test.ts:94-94
Timestamp: 2025-04-04T11:25:21.518Z
Learning: In the rain.orderbook project, minimal test fixtures are preferred over complete mocks that implement the entire interface. Type casting (e.g., `as unknown as SgVault`) is an acceptable approach to maintain both minimal fixtures and TypeScript type compatibility.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1925
File: crates/settings/src/remote_tokens.rs:44-62
Timestamp: 2025-07-11T08:45:43.961Z
Learning: findolor prefers to avoid performance micro-optimizations like changing `.values()` to `.into_values()` in HashMap iterations in the rainlanguage/rain.orderbook codebase, even when they would eliminate unnecessary cloning.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1903
File: crates/js_api/src/subgraph/vault.rs:129-138
Timestamp: 2025-06-17T16:33:58.549Z
Learning: findolor prefers downstream error handling over early validation checks for empty RPC lists in vault functions, allowing errors to bubble up from provider creation logic naturally.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1975
File: crates/js_api/src/config.rs:44-45
Timestamp: 2025-07-09T07:42:48.458Z
Learning: User findolor prefers to defer code improvements and refactoring suggestions to future PRs when they are not directly related to the current PR's scope, even when the suggestions are valid improvements.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1947
File: crates/common/src/raindex_client/orders.rs:462-1643
Timestamp: 2025-06-24T08:45:10.971Z
Learning: User findolor prefers to keep tests simple and avoid refactoring for maintainability when the code is stable and viewed as "one time thing" that won't require frequent changes.

Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#0
File: :0-0
Timestamp: 2025-05-21T23:34:42.328Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, the PR size report must use the format:
TOTAL:number
ADDITIONS:number
DELETIONS:number
with no extra text, formatting blocks, or explanations, and must still exclude lock files and reassess after each new commit.

Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#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
PR: rainlanguage/rain.orderbook#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
PR: rainlanguage/rain.orderbook#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
PR: rainlanguage/rain.orderbook#0
File: :0-0
Timestamp: 2025-05-21T22:47:21.927Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, the PR size report must always be placed at the very beginning of any comment, before any learning used section or other content.

Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#0
File: :0-0
Timestamp: 2025-05-21T22:47:21.927Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, the PR size report must always be placed at the very beginning of any comment, before any learning used section or other content.

Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#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
PR: rainlanguage/rain.orderbook#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
PR: rainlanguage/rain.orderbook#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.

Comment on lines +62 to +69
max_output: value.max_output,
formatted_max_output: format_amount_u256(value.max_output, 18)?,
max_input,
formatted_max_input: format_amount_u256(max_input, 36)?,
ratio: value.ratio,
formatted_ratio: format_amount_u256(value.ratio, 18)?,
inverse_ratio,
formatted_inverse_ratio: format_amount_u256(inverse_ratio, 18)?,
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot Jul 16, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue

Hardcoded decimal values may not be appropriate for all tokens

The formatting uses hardcoded decimal values (18 for most fields, 36 for max_input) which might not match the actual token decimals. This could lead to incorrect display values.

Consider using the actual token decimals from the order's input/output vaults instead of hardcoded values. The token information should be available through the order structure.

🤖 Prompt for AI Agents
In crates/common/src/raindex_client/order_quotes.rs around lines 62 to 69, the
code uses hardcoded decimal values (18 and 36) for formatting amounts, which may
not match the actual token decimals. To fix this, retrieve the correct decimal
values from the order's input and output vault token metadata instead of using
fixed numbers. Replace the hardcoded decimals in the format_amount_u256 calls
with these dynamic decimals to ensure accurate formatting for all tokens.

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 fine for our use case

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've noted that the hardcoded decimal values are intentional for your use case.

🐰
◕ ◕
( ‿ )
︶ ︶


✏️ Learnings added
Learnt from: findolor
PR: rainlanguage/rain.orderbook#2001
File: crates/common/src/raindex_client/order_quotes.rs:62-69
Timestamp: 2025-07-16T14:33:13.409Z
Learning: In the rainlanguage/rain.orderbook codebase, findolor considers hardcoded decimal values (18 and 36) in order quote formatting logic to be acceptable for their use case, even when dynamic token decimals could theoretically provide more accurate formatting for different tokens.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: findolor
PR: rainlanguage/rain.orderbook#2000
File: crates/common/src/raindex_client/vaults.rs:183-183
Timestamp: 2025-07-16T10:40:05.656Z
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.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1956
File: crates/common/src/raindex_client/orders.rs:609-609
Timestamp: 2025-07-04T10:27:22.544Z
Learning: In the rainlanguage/rain.orderbook codebase, user findolor prefers not to implement overflow protection for trades count casting (usize to u16) at this time, considering it unnecessary for the current scope since the practical risk of orders having 65,535+ trades is extremely low.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1956
File: crates/common/src/raindex_client/trades.rs:215-223
Timestamp: 2025-07-04T10:24:56.163Z
Learning: In the rain.orderbook codebase, the get_trade_count method implementation that fetches all trades to count them is intentionally consistent with previous implementations and not considered a performance issue, as indicated by findolor for the trades counting functionality in crates/common/src/raindex_client/trades.rs.

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.

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.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1706
File: crates/quote/src/js_api/mod.rs:57-61
Timestamp: 2025-04-29T06:19:15.446Z
Learning: In the rain.orderbook codebase, the `get_id` function is designed to use `U256::from_str()` rather than `U256::from_hex()` for parsing order hashes, despite the potential for hex string inputs.

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.

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.

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.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1994
File: crates/common/src/raindex_client/vaults.rs:59-59
Timestamp: 2025-07-16T05:52:05.538Z
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.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1956
File: crates/common/src/fuzz/mod.rs:64-64
Timestamp: 2025-07-04T09:02:57.301Z
Learning: In rainlanguage/rain.orderbook, user findolor prefers to limit type consistency changes to only the parts directly related to the current work scope. For example, when updating chain_id fields from u64 to u32 in fuzz-related code, unrelated files like tauri-app wallet commands can remain as u64 if they serve different purposes and aren't part of the current changes.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1983
File: crates/settings/src/gui.rs:965-973
Timestamp: 2025-07-11T08:37:24.423Z
Learning: In the rainlanguage/rain.orderbook project, user findolor prefers to keep user-facing error messages generic and user-friendly rather than technically specific. For example, using "a valid number" instead of "a valid u8 (0-255)" in GUI validation error messages to maintain simplicity for end users.

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.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1903
File: crates/settings/src/yaml/orderbook.rs:371-377
Timestamp: 2025-06-17T16:21:24.384Z
Learning: In crates/settings/src/yaml/orderbook.rs tests, the user findolor considers RPC ordering in Vec<Url> assertions to be intentional and not a test brittleness issue. The ordering of RPCs in tests should be preserved as specified.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1938
File: crates/js_api/src/raindex/mod.rs:102-118
Timestamp: 2025-06-18T12:56:44.290Z
Learning: In the rainlanguage/rain.orderbook codebase, it's acceptable to scaffold unused enum variants in initial implementation PRs when they will be implemented in future PRs, as confirmed by findolor.

Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#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
PR: rainlanguage/rain.orderbook#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
PR: rainlanguage/rain.orderbook#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
PR: rainlanguage/rain.orderbook#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
PR: rainlanguage/rain.orderbook#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).

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1715
File: crates/js_api/src/common/mod.rs:55-59
Timestamp: 2025-05-14T05:51:50.277Z
Learning: In the Rain Orderbook project, the error handling for WASM exported functions uses WasmEncodedError which includes both the original error message and a human-readable version, making direct modification of the JsValue conversion unnecessary.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1925
File: crates/settings/src/remote_tokens.rs:44-62
Timestamp: 2025-07-11T08:45:43.961Z
Learning: findolor prefers to avoid performance micro-optimizations like changing `.values()` to `.into_values()` in HashMap iterations in the rainlanguage/rain.orderbook codebase, even when they would eliminate unnecessary cloning.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1903
File: crates/js_api/src/subgraph/vault.rs:129-138
Timestamp: 2025-06-17T16:33:58.549Z
Learning: findolor prefers downstream error handling over early validation checks for empty RPC lists in vault functions, allowing errors to bubble up from provider creation logic naturally.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1916
File: packages/webapp/src/routes/+layout.ts:26-26
Timestamp: 2025-06-10T12:01:07.418Z
Learning: The user findolor prefers to keep string concatenation using the plus operator over template literals in the rainlanguage/rain.orderbook project, even when static analysis tools suggest the change.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1975
File: crates/js_api/src/config.rs:44-45
Timestamp: 2025-07-09T07:42:48.458Z
Learning: User findolor prefers to defer code improvements and refactoring suggestions to future PRs when they are not directly related to the current PR's scope, even when the suggestions are valid improvements.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1947
File: crates/common/src/raindex_client/orders.rs:462-1643
Timestamp: 2025-06-24T08:45:10.971Z
Learning: User findolor prefers to keep tests simple and avoid refactoring for maintainability when the code is stable and viewed as "one time thing" that won't require frequent changes.

Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#0
File: :0-0
Timestamp: 2025-05-21T23:34:42.328Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, the PR size report must use the format:
TOTAL:number
ADDITIONS:number
DELETIONS:number
with no extra text, formatting blocks, or explanations, and must still exclude lock files and reassess after each new commit.

Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#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
PR: rainlanguage/rain.orderbook#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
PR: rainlanguage/rain.orderbook#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
PR: rainlanguage/rain.orderbook#0
File: :0-0
Timestamp: 2025-05-21T22:47:21.927Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, the PR size report must always be placed at the very beginning of any comment, before any learning used section or other content.

Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#0
File: :0-0
Timestamp: 2025-05-21T22:47:21.927Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, the PR size report must always be placed at the very beginning of any comment, before any learning used section or other content.

Comment on lines +2338 to +2388
#[tokio::test]
async fn test_get_account_balance_from_token() {
let server = MockServer::start_async().await;
server.mock(|when, then| {
when.path("/sg1");
then.status(200).json_body_obj(&json!({
"data": {
"vault": get_vault1_json()
}
}));
});
server.mock(|when, then| {
when.method("POST")
.path("/rpc1")
.body_contains("0x70a08231");
then.body(
Response::new_success(
1,
"0x00000000000000000000000000000000000000000000000000000000000003e8",
)
.to_json_string()
.unwrap(),
);
});

let raindex_client = RaindexClient::new(
vec![get_test_yaml(
&server.url("/sg1"),
&server.url("/sg2"),
&server.url("/rpc1"),
&server.url("/rpc2"),
)],
None,
)
.unwrap();
let vault = raindex_client
.get_vault(
1,
Address::from_str(CHAIN_ID_1_ORDERBOOK_ADDRESS).unwrap(),
Bytes::from_str("0x0123").unwrap(),
)
.await
.unwrap();

let balance = vault
.token
.get_account_balance(Address::random())
.await
.unwrap();
assert_eq!(balance, U256::from(1000));
}
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot Jul 16, 2025

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Use a fixed address for deterministic testing.

The test uses Address::random() which could make the test non-deterministic. Consider using a fixed address for better test reproducibility.

-            let balance = vault
-                .token
-                .get_account_balance(Address::random())
-                .await
-                .unwrap();
+            let test_address = Address::from_str("0x1234567890123456789012345678901234567890").unwrap();
+            let balance = vault
+                .token
+                .get_account_balance(test_address)
+                .await
+                .unwrap();
📝 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
#[tokio::test]
async fn test_get_account_balance_from_token() {
let server = MockServer::start_async().await;
server.mock(|when, then| {
when.path("/sg1");
then.status(200).json_body_obj(&json!({
"data": {
"vault": get_vault1_json()
}
}));
});
server.mock(|when, then| {
when.method("POST")
.path("/rpc1")
.body_contains("0x70a08231");
then.body(
Response::new_success(
1,
"0x00000000000000000000000000000000000000000000000000000000000003e8",
)
.to_json_string()
.unwrap(),
);
});
let raindex_client = RaindexClient::new(
vec![get_test_yaml(
&server.url("/sg1"),
&server.url("/sg2"),
&server.url("/rpc1"),
&server.url("/rpc2"),
)],
None,
)
.unwrap();
let vault = raindex_client
.get_vault(
1,
Address::from_str(CHAIN_ID_1_ORDERBOOK_ADDRESS).unwrap(),
Bytes::from_str("0x0123").unwrap(),
)
.await
.unwrap();
let balance = vault
.token
.get_account_balance(Address::random())
.await
.unwrap();
assert_eq!(balance, U256::from(1000));
}
#[tokio::test]
async fn test_get_account_balance_from_token() {
let server = MockServer::start_async().await;
server.mock(|when, then| {
when.path("/sg1");
then.status(200).json_body_obj(&json!({
"data": {
"vault": get_vault1_json()
}
}));
});
server.mock(|when, then| {
when.method("POST")
.path("/rpc1")
.body_contains("0x70a08231");
then.body(
Response::new_success(
1,
"0x00000000000000000000000000000000000000000000000000000000000003e8",
)
.to_json_string()
.unwrap(),
);
});
let raindex_client = RaindexClient::new(
vec![get_test_yaml(
&server.url("/sg1"),
&server.url("/sg2"),
&server.url("/rpc1"),
&server.url("/rpc2"),
)],
None,
)
.unwrap();
let vault = raindex_client
.get_vault(
1,
Address::from_str(CHAIN_ID_1_ORDERBOOK_ADDRESS).unwrap(),
Bytes::from_str("0x0123").unwrap(),
)
.await
.unwrap();
let test_address = Address::from_str("0x1234567890123456789012345678901234567890").unwrap();
let balance = vault
.token
.get_account_balance(test_address)
.await
.unwrap();
assert_eq!(balance, U256::from(1000));
}
🤖 Prompt for AI Agents
In crates/common/src/raindex_client/vaults.rs around lines 2338 to 2388, the
test_get_account_balance_from_token function uses Address::random() which makes
the test non-deterministic. Replace Address::random() with a fixed, hardcoded
address value to ensure the test produces consistent and reproducible results
every time it runs.

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.

address is not used so this is valid code

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 You're absolutely right! Looking at the mock setup, the server only checks for the balanceOf function selector (0x70a08231) and returns a fixed response of 1000, regardless of which address is passed as the parameter. Since the mock doesn't validate the actual address value, using Address::random() doesn't make the test non-deterministic - it will always return the same mocked result.

Thanks for the clarification. The test is indeed deterministic in this context.

🐰
/| /|
( ✌️ )
|()|
O
("_")_O


✏️ Learnings added
Learnt from: findolor
PR: rainlanguage/rain.orderbook#2001
File: crates/common/src/raindex_client/vaults.rs:0-0
Timestamp: 2025-07-16T14:33:45.855Z
Learning: In the rainlanguage/rain.orderbook codebase, findolor considers using Address::random() in tests to be acceptable when the mock server doesn't validate the address parameter and returns a fixed response, making the test deterministic regardless of the address value used.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
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.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#2000
File: crates/common/src/raindex_client/vaults.rs:183-183
Timestamp: 2025-07-16T10:40:05.656Z
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.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1903
File: crates/settings/src/yaml/orderbook.rs:371-377
Timestamp: 2025-06-17T16:21:24.384Z
Learning: In crates/settings/src/yaml/orderbook.rs tests, the user findolor considers RPC ordering in Vec<Url> assertions to be intentional and not a test brittleness issue. The ordering of RPCs in tests should be preserved as specified.

Learnt from: 0xgleb
PR: rainlanguage/rain.orderbook#1844
File: tauri-app/src-tauri/src/commands/wallet.rs:27-28
Timestamp: 2025-05-16T17:24:34.724Z
Learning: In Rust projects, dependencies listed in the [dependencies] section of Cargo.toml are available for both application code and tests. The tokio crate with the "full" feature set includes the "test" feature needed for `#[tokio::test]` to work properly.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1872
File: packages/webapp/src/__tests__/handleVaultDeposit.test.ts:20-53
Timestamp: 2025-06-07T05:19:46.330Z
Learning: In the rain.orderbook codebase, simple wrapper/adapter functions that just delegate to other functions (like handleVaultDeposit) don't need extensive edge case testing for missing parameters or error handling - the current test coverage focusing on core functionality is sufficient.

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.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1994
File: crates/common/src/raindex_client/vaults.rs:59-59
Timestamp: 2025-07-16T05:52:05.538Z
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.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1874
File: tauri-app/src-tauri/src/transaction_status.rs:69-127
Timestamp: 2025-05-27T06:16:35.738Z
Learning: In tauri-app/src-tauri/src/transaction_status.rs, directly accessing internal RwLock state in tests using `notice.0.read().unwrap()` is acceptable and does not require encapsulation through public getter methods.

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.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1483
File: crates/settings/src/remote_tokens.rs:32-57
Timestamp: 2025-04-07T09:51:52.614Z
Learning: The implementation for remote token fetching in `crates/settings/src/remote_tokens.rs` does not include explicit timeouts/retries, as the team considers the current implementation sufficient for now.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1882
File: packages/webapp/src/lib/services/handleVaultDeposit.ts:96-125
Timestamp: 2025-06-07T09:07:53.733Z
Learning: In the vault deposit flow, vault.token.address is already validated before reaching the approval transaction creation, so casting it to Hex type is safe and doesn't require additional validation.

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.

Learnt from: thedavidmeister
PR: rainlanguage/rain.orderbook#1926
File: test/concrete/ob/OrderBook.clear.zeroAmount.t.sol:24-32
Timestamp: 2025-06-16T10:49:47.770Z
Learning: LibTestAddOrder.conformConfig() in test/util/lib/LibTestAddOrder.sol automatically constrains OrderConfigV3 to prevent common test failures by ensuring validInputs[0].token != validOutputs[0].token, setting them to address(0) and address(1) respectively if they're equal. This prevents TokenSelfTrade errors in fuzz tests.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1925
File: crates/settings/src/remote_tokens.rs:44-62
Timestamp: 2025-07-11T08:45:43.961Z
Learning: findolor prefers to avoid performance micro-optimizations like changing `.values()` to `.into_values()` in HashMap iterations in the rainlanguage/rain.orderbook codebase, even when they would eliminate unnecessary cloning.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1903
File: crates/js_api/src/subgraph/vault.rs:129-138
Timestamp: 2025-06-17T16:33:58.549Z
Learning: findolor prefers downstream error handling over early validation checks for empty RPC lists in vault functions, allowing errors to bubble up from provider creation logic naturally.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1916
File: packages/webapp/src/routes/+layout.ts:26-26
Timestamp: 2025-06-10T12:01:07.418Z
Learning: The user findolor prefers to keep string concatenation using the plus operator over template literals in the rainlanguage/rain.orderbook project, even when static analysis tools suggest the change.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1975
File: crates/js_api/src/config.rs:44-45
Timestamp: 2025-07-09T07:42:48.458Z
Learning: User findolor prefers to defer code improvements and refactoring suggestions to future PRs when they are not directly related to the current PR's scope, even when the suggestions are valid improvements.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#1947
File: crates/common/src/raindex_client/orders.rs:462-1643
Timestamp: 2025-06-24T08:45:10.971Z
Learning: User findolor prefers to keep tests simple and avoid refactoring for maintainability when the code is stable and viewed as "one time thing" that won't require frequent changes.

Learnt from: findolor
PR: rainlanguage/rain.orderbook#2001
File: crates/common/src/raindex_client/order_quotes.rs:62-69
Timestamp: 2025-07-16T14:33:13.409Z
Learning: In the rainlanguage/rain.orderbook codebase, findolor considers hardcoded decimal values (18 and 36) in order quote formatting logic to be acceptable for their use case, even when dynamic token decimals could theoretically provide more accurate formatting for different tokens.

Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#0
File: :0-0
Timestamp: 2025-05-21T23:34:42.328Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, the PR size report must use the format:
TOTAL:number
ADDITIONS:number
DELETIONS:number
with no extra text, formatting blocks, or explanations, and must still exclude lock files and reassess after each new commit.

Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#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
PR: rainlanguage/rain.orderbook#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).

Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#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
PR: rainlanguage/rain.orderbook#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
PR: rainlanguage/rain.orderbook#0
File: :0-0
Timestamp: 2025-05-21T22:47:21.927Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, the PR size report must always be placed at the very beginning of any comment, before any learning used section or other content.

Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#0
File: :0-0
Timestamp: 2025-05-21T22:47:21.927Z
Learning: For PR #1884 in rainlanguage/rain.orderbook, the PR size report must always be placed at the very beginning of any comment, before any learning used section or other content.

Learnt from: rouzwelt
PR: rainlanguage/rain.orderbook#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
PR: rainlanguage/rain.orderbook#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
PR: rainlanguage/rain.orderbook#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.

#[serde(rename_all = "camelCase")]
#[wasm_bindgen]
pub struct RaindexVaultToken {
raindex_client: Arc<RwLock<RaindexClient>>,
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 (assertive)

Architectural consideration: Circular reference pattern introduced.

Adding raindex_client to RaindexVaultToken creates a circular dependency between the token and client. While Arc<RwLock<>> prevents memory issues, this increases architectural complexity. Consider documenting this design decision for future maintainers.

🤖 Prompt for AI Agents
In crates/common/src/raindex_client/vaults.rs at line 177, the addition of
raindex_client as an Arc<RwLock<RaindexClient>> in RaindexVaultToken introduces
a circular reference pattern. To address this, add clear documentation comments
near this field explaining the intentional circular dependency and the use of
Arc<RwLock<>> to manage memory safely, so future maintainers understand the
architectural decision and complexity involved.

Comment on lines +259 to +271
pub async fn get_account_balance_wasm_binding(
&self,
#[wasm_export(param_description = "Account address to check balance for")] account: String,
) -> Result<AccountBalance, RaindexError> {
let account = Address::from_str(&account)?;
let balance = self.clone().get_account_balance(account).await?;
let decimals = self.decimals.try_into()?;
let account_balance = AccountBalance {
balance,
formatted_balance: format_amount_u256(balance, decimals)?,
};
Ok(account_balance)
}
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.

🛠️ Refactor suggestion

Avoid unnecessary cloning in get_account_balance call.

The method clones self when calling get_account_balance, but this is unnecessary since the method only needs to read the token's fields.

-        let balance = self.clone().get_account_balance(account).await?;
+        let balance = self.get_account_balance(account).await?;

Then update the get_account_balance method signature to take &self instead of self:

-    pub async fn get_account_balance(self, account: Address) -> Result<U256, RaindexError> {
+    pub async fn get_account_balance(&self, account: Address) -> Result<U256, RaindexError> {
🤖 Prompt for AI Agents
In crates/common/src/raindex_client/vaults.rs around lines 259 to 271, remove
the unnecessary cloning of self when calling get_account_balance by changing the
call from self.clone().get_account_balance(account).await to
self.get_account_balance(account).await. Then update the get_account_balance
method signature to accept &self instead of self to allow calling it without
cloning.

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

🔭 Outside diff range comments (1)
packages/ui-components/src/__tests__/TanstackOrderQuote.test.ts (1)

240-248: Update test data to use formatted fields.

This test case still uses raw hex values (maxOutput, ratio) instead of the formatted fields (formattedMaxOutput, formattedRatio) that the component now expects. This inconsistency may cause test failures.

Apply this diff to fix the test data:

-					data: { maxOutput: '0x158323e942e36d8c', ratio: '0x5b16799fcb6114f7' },
+					data: { formattedMaxOutput: '1.550122181502135692', formattedRatio: '6.563567234157974775' },
-					data: { maxOutput: '0x54fa82f5c7001dad', ratio: '0x53e0089714d06709' },
+					data: { formattedMaxOutput: '6.066479884955967059', formattedRatio: '6.485589855485802559' },
♻️ Duplicate comments (4)
packages/ui-components/src/lib/components/detail/TanstackOrderQuote.svelte (1)

114-120: LGTM: Template simplified with pre-formatted fields.

The template now uses pre-formatted fields (formattedMaxOutput, formattedRatio, formattedInverseRatio, formattedMaxInput) instead of inline formatting with formatUnits. This is a clean architectural improvement that:

  • Reduces template complexity
  • Moves formatting logic to the backend
  • Ensures consistent formatting across the application
  • Improves maintainability
packages/ui-components/src/lib/services/historicalOrderCharts.ts (1)

18-21: Potential precision loss when converting formatted strings to numbers

Converting formatted decimal strings to JavaScript Number type can lead to precision loss for large values. Consider using a decimal arithmetic library like decimal.js for accurate calculations.

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

2346-2346: Use a fixed address for deterministic testing.

The test uses Address::random() which could make the test non-deterministic. Consider using a fixed address for better test reproducibility.

-            let balance = vault.get_owner_balance(Address::random()).await.unwrap();
+            let test_address = Address::from_str("0x1234567890123456789012345678901234567890").unwrap();
+            let balance = vault.get_owner_balance(test_address).await.unwrap();
crates/common/src/raindex_client/order_quotes.rs (1)

62-70: Hardcoded decimal values may not be appropriate for all tokens.

The formatting uses hardcoded decimal values (18 for most fields, 36 for max_input) which might not match the actual token decimals. This could lead to incorrect display values.

Consider retrieving the actual token decimals from the order's input/output vaults instead of using hardcoded values.

Comment thread crates/common/src/raindex_client/vaults.rs Outdated
@findolor findolor enabled auto-merge July 16, 2025 19:23
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