-
Notifications
You must be signed in to change notification settings - Fork 6
Move common js_api file to main js_api directory and add tests #1715
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
WalkthroughThis change removes the WASM JavaScript API module ( Changes
Sequence Diagram(s)sequenceDiagram
participant JS as JavaScript (WebApp)
participant WASM as WASM Bindgen (js_api/common)
participant Rust as Rust Core Logic
participant RPC as Mocked RPC Server
JS->>WASM: getAddOrderCalldata(dotrain, deployment)
WASM->>Rust: parse frontmatter, validate deployment
Rust->>RPC: fetch blockchain state (mocked)
RPC-->>Rust: return mocked responses
Rust->>WASM: generate calldata bytes
WASM-->>JS: return AddOrderCalldata (or Error)
JS->>WASM: getRemoveOrderCalldata(order)
WASM->>Rust: prepare remove order args
Rust->>WASM: generate calldata bytes
WASM-->>JS: return RemoveOrderCalldata (or Error)
Assessment against linked issues
Possibly related PRs
Suggested reviewers
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
🔭 Outside diff range comments (2)
packages/orderbook/test/common/test.test.ts (2)
77-84
: 🧹 Nitpick (assertive)Trim whitespace before comparison to avoid brittle failures
DotrainOrder.composeDeploymentToRainlang
might emit or omit trailing/leading new-lines depending on microscopic changes in the compiler or running OS.
A strict equality check will break the build for purely cosmetic newline differences.- assert.equal(result, expected); + assert.equal(result.trim(), expected.trim());Do the same for the second expectation below to keep both tests robust.
97-104
: 🧹 Nitpick (assertive)See the note above – apply
.trim()
here as well to make the test future-proof.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (2)
Cargo.lock
is excluded by!**/*.lock
tauri-app/src-tauri/Cargo.lock
is excluded by!**/*.lock
📒 Files selected for processing (15)
Cargo.toml
(1 hunks)crates/common/src/frontmatter.rs
(1 hunks)crates/common/src/js_api/mod.rs
(0 hunks)crates/common/src/lib.rs
(1 hunks)crates/common/src/test_helpers.rs
(2 hunks)crates/js_api/Cargo.toml
(1 hunks)crates/js_api/src/common/mod.rs
(1 hunks)crates/js_api/src/gui/state_management.rs
(1 hunks)crates/js_api/src/lib.rs
(1 hunks)crates/subgraph/Cargo.toml
(0 hunks)crates/subgraph/src/types/common.rs
(22 hunks)packages/orderbook/test/common/test.test.ts
(1 hunks)packages/orderbook/test/js_api/common.test.ts
(1 hunks)packages/webapp/src/__tests__/OrderRemoveModal.test.ts
(1 hunks)packages/webapp/src/lib/components/OrderRemoveModal.svelte
(1 hunks)
💤 Files with no reviewable changes (2)
- crates/subgraph/Cargo.toml
- crates/common/src/js_api/mod.rs
🧰 Additional context used
🧠 Learnings (1)
packages/webapp/src/lib/components/OrderRemoveModal.svelte (1)
Learnt from: hardingjam
PR: rainlanguage/rain.orderbook#1512
File: packages/ui-components/src/__tests__/OrderDetail.test.ts:0-0
Timestamp: 2025-04-09T09:28:05.097Z
Learning: The OrderDetail component has been refactored to use an `onRemove` callback approach instead of the previous `handleOrderRemoveModal` pattern for order removal functionality, as part of PR #1512.
🪛 Biome (1.9.4)
packages/orderbook/test/js_api/common.test.ts
[error] 145-145: This let declares a variable that is only assigned once.
'order' is never reassigned.
Safe fix: Use const instead.
(lint/style/useConst)
⏰ Context from checks skipped due to timeout of 90000ms (16)
- GitHub Check: build-tauri (ubuntu-22.04, true)
- GitHub Check: git-clean
- GitHub Check: test
- GitHub Check: test
- GitHub Check: test
- GitHub Check: standard-tests (ubuntu-latest, test-js-bindings)
- GitHub Check: standard-tests (ubuntu-latest, rainix-sol-test)
- GitHub Check: standard-tests (ubuntu-latest, rainix-wasm-artifacts)
- GitHub Check: Deploy-Preview
- GitHub Check: standard-tests (ubuntu-latest, rainix-sol-static)
- GitHub Check: standard-tests (ubuntu-latest, rainix-rs-artifacts, true)
- GitHub Check: standard-tests (ubuntu-latest, ob-rs-test, true)
- GitHub Check: standard-tests (ubuntu-latest, rainix-wasm-test)
- GitHub Check: standard-tests (ubuntu-latest, rainix-sol-legal)
- GitHub Check: standard-tests (ubuntu-latest, rainix-sol-artifacts)
- GitHub Check: standard-tests (ubuntu-latest, rainix-rs-static)
🔇 Additional comments (14)
crates/js_api/src/gui/state_management.rs (1)
291-291
: Good move restricting JS interop utilities to test code.Importing
js_sys::{eval, Reflect}
only within the test module is a better practice than having it in the main module scope, as it limits the exposure of JS interop to testing code.crates/common/src/frontmatter.rs (1)
164-164
: Test assertions updated to match numeric values.The test assertions have been correctly updated to reflect the changes in test data, where string values like "value1" and "value2" were replaced with numeric values "10" and "20".
Also applies to: 170-170
Cargo.toml (1)
56-56
:✅ Verification successful
Consider trade-offs of Git dependency versus published crate.
Switching from a versioned crate
"0.0.7"
to a Git repository with a specific commit hash ensures reproducible builds but may make it harder to track and update dependencies.
🏁 Script executed:
#!/bin/bash # Check if wasm-bindgen-utils is used in other repos that might be affected by this change # Look for the package in the workspace echo "Checking usage of wasm-bindgen-utils in the workspace:" rg "wasm-bindgen-utils" --type rust # Check if any other dependencies are using git references echo -e "\nChecking for other git dependencies in Cargo.toml:" rg "git =" Cargo.tomlLength of output: 801
No action needed: Git dependency is consistent with other internal crates
This workspace already pulls all internal
rainlanguage
crates directly from Git (ensuring reproducible builds), including:
alloy-ethers-typecast
rain-erc
rain-error-decoding
wasm-bindgen-utils
Switching
wasm-bindgen-utils
to a Git reference aligns with the existing practice. No changes required.packages/webapp/src/__tests__/OrderRemoveModal.test.ts (1)
8-10
: Mock updated to match the new return type structure.The mock implementation has been correctly updated to return a structured object with a
value
property, which aligns with the new WASM bindings return type ingetRemoveOrderCalldata
.crates/js_api/Cargo.toml (1)
36-38
: Good addition of conditional dev-dependency for testingAdding
httpmock
as a dev-dependency only for non-WASM targets is a good approach. This will allow for proper HTTP mocking in tests while keeping the WASM build clean.crates/js_api/src/lib.rs (1)
1-2
: Appropriate conditional compilation for improved testabilityExposing the
common
module for both WASM and test environments is a good approach. This ensures the module can be properly tested without needing to compile for WASM specifically.packages/webapp/src/lib/components/OrderRemoveModal.svelte (1)
27-36
: Improved error handling for the new API structureThe updated code properly handles the new return structure from
getRemoveOrderCalldata
, checking for errors before proceeding with the transaction. This is a good improvement that provides clearer error reporting to users.crates/common/src/test_helpers.rs (1)
60-66
: Values changed to numbers – looks goodBindings
key1
andkey2
were migrated from strings to numbers and the YAML / front-matter stay in sync with the updated Rust tests.packages/orderbook/test/js_api/common.test.ts (1)
8-9
: AwaitmockServer.start/stop
for deterministic setup & teardown
mockttp
returns a Promise from bothstart
andstop
. Although Vitest handles returned Promises, being explicit avoids foot-guns if the function signature ever changes.-beforeEach(() => mockServer.start(8080)); -afterEach(() => mockServer.stop()); +beforeEach(async () => { await mockServer.start(8080); }); +afterEach(async () => { await mockServer.stop(); });crates/subgraph/src/types/common.rs (5)
3-3
: LGTM: Unconditional import of wasm_bindgen_utils.The import is now unconditional rather than being wrapped in a
#[cfg(target_family = "wasm")]
directive, which aligns with the refactoring effort to centralize WASM-related functionality.
5-5
: LGTM: Standardizing Tsify derivation.The
Tsify
derive macro is now applied unconditionally to all relevant structs and enums, which ensures consistent TypeScript type definitions. This change supports the centralized WASM binding approach in the js_api crate.Also applies to: 11-11, 21-21, 29-29, 40-40, 51-51, 60-60, 73-73, 82-82, 103-103, 110-110, 118-118, 127-127, 134-134, 144-144, 155-155, 175-175, 182-182, 191-191, 206-206, 219-219, 235-235, 251-251, 267-267, 284-284, 291-291, 304-304, 310-310, 323-323, 333-333, 340-340, 347-347, 354-354, 361-361, 365-365
101-101
: LGTM: Relocated WASM trait implementations.The
impl_wasm_traits!
macro invocations forSgOrder
andSgVault
have been moved from the conditionalimpls
module to appear directly after their respective struct definitions. This improves code readability by keeping related implementations together.Also applies to: 173-173
338-338
: LGTM: New WASM trait implementations for order operations.New
impl_wasm_traits!
invocations forSgAddOrder
andSgRemoveOrder
support the js_api crate's functions for generating order calldata. This enables proper serialization/deserialization when these types cross the Rust/JavaScript boundary.Also applies to: 345-345
657-679
: LGTM: Remaining WASM trait implementations are still conditionally defined.The module containing additional
impl_wasm_traits!
invocations is still conditionally compiled only for WASM targets. This is appropriate for types that aren't directly used by the centralized js_api functions but still need WASM interoperability when targeting WASM.
it('should get correct calldata', async () => { | ||
// mock calls | ||
// iInterpreter() call | ||
await mockServer | ||
.forPost('/rpc-url') | ||
.withBodyIncluding('0xf0cfdd37') | ||
.thenSendJsonRpcResult(`0x${'0'.repeat(24) + '1'.repeat(40)}`); | ||
// iStore() call | ||
await mockServer | ||
.forPost('/rpc-url') | ||
.withBodyIncluding('0xc19423bc') | ||
.thenSendJsonRpcResult(`0x${'0'.repeat(24) + '2'.repeat(40)}`); | ||
// iParser() call | ||
await mockServer | ||
.forPost('/rpc-url') | ||
.withBodyIncluding('0x24376855') | ||
.thenSendJsonRpcResult(`0x${'0'.repeat(24) + '3'.repeat(40)}`); | ||
// parse2() call | ||
await mockServer | ||
.forPost('/rpc-url') | ||
.withBodyIncluding('0xa3869e14') | ||
// 0x1234 encoded bytes | ||
.thenSendJsonRpcResult( | ||
'0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000021234000000000000000000000000000000000000000000000000000000000000' | ||
); | ||
|
||
const result = await getAddOrderCalldata(dotrain, 'some-deployment'); | ||
if (result.error) assert.fail('expected no error'); | ||
assert.equal(result.value.length, 2314); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Magic constant 2314 – document or derive
The length 2314
appears arbitrary to a future reader. Consider:
assert.equal(result.value.length, expectedCalldata.length);
…where expectedCalldata
is produced through the same Rust helper (as done in the non-wasm test below). This prevents silent breakages if the ABI encoding ever changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to do this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@findolor Understood, I'll respect your preference for keeping the constant as is.
let order: SgOrder = { | ||
id: '1', | ||
orderBytes: | ||
'0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000006171c21b2e553c59a64d1337211b77c367cefe5d00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000379b966dc6b117dd47b5fc5308534256a4ab1bcc0000000000000000000000006e4b01603edbda617002a077420e98c86595748e000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000950000000000000000000000000000000000000000000000000000000000000002ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000015020000000c020200020110000001100001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000050c5725949a6f0c72e6c4a641f24049a917db0cb000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda0291300000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001', | ||
orderHash: '', | ||
owner: '', | ||
active: true, | ||
inputs: [], | ||
outputs: [], | ||
meta: undefined, | ||
orderbook: { | ||
id: '1' | ||
}, | ||
addEvents: [], | ||
timestampAdded: '0', | ||
trades: [], | ||
removeEvents: [] | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Use const
instead of let
for the immutable order
object
Static-analysis is right: order
is never reassigned, so const
communicates intent and prevents accidental mutation.
- let order: SgOrder = {
+ const order: SgOrder = {
📝 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.
let order: SgOrder = { | |
id: '1', | |
orderBytes: | |
'0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000006171c21b2e553c59a64d1337211b77c367cefe5d00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000379b966dc6b117dd47b5fc5308534256a4ab1bcc0000000000000000000000006e4b01603edbda617002a077420e98c86595748e000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000950000000000000000000000000000000000000000000000000000000000000002ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000015020000000c020200020110000001100001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000050c5725949a6f0c72e6c4a641f24049a917db0cb000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda0291300000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001', | |
orderHash: '', | |
owner: '', | |
active: true, | |
inputs: [], | |
outputs: [], | |
meta: undefined, | |
orderbook: { | |
id: '1' | |
}, | |
addEvents: [], | |
timestampAdded: '0', | |
trades: [], | |
removeEvents: [] | |
}; | |
const order: SgOrder = { | |
id: '1', | |
orderBytes: | |
'0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000006171c21b2e553c59a64d1337211b77c367cefe5d00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000379b966dc6b117dd47b5fc5308534256a4ab1bcc0000000000000000000000006e4b01603edbda617002a077420e98c86595748e000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000950000000000000000000000000000000000000000000000000000000000000002ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000000000000000015020000000c020200020110000001100001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000050c5725949a6f0c72e6c4a641f24049a917db0cb000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda0291300000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001', | |
orderHash: '', | |
owner: '', | |
active: true, | |
inputs: [], | |
outputs: [], | |
meta: undefined, | |
orderbook: { | |
id: '1' | |
}, | |
addEvents: [], | |
timestampAdded: '0', | |
trades: [], | |
removeEvents: [] | |
}; |
🧰 Tools
🪛 Biome (1.9.4)
[error] 145-145: This let declares a variable that is only assigned once.
'order' is never reassigned.
Safe fix: Use const instead.
(lint/style/useConst)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to do this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@findolor Understood, I'll respect your preference and won't pursue this change. Thanks for the feedback.
#[cfg(target_family = "wasm")] | ||
mod wasm_tests { | ||
use super::*; | ||
use alloy::{ | ||
primitives::{Address, FixedBytes, U256}, | ||
sol_types::SolCall, | ||
}; | ||
use rain_orderbook_bindings::IOrderBookV4::{removeOrder2Call, EvaluableV3, OrderV3, IO}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Keep platform-specific tests mutually exclusive
#[cfg(target_family = "wasm")]
+ wasm_bindgen_test
combo is great, but remember that wasm_bindgen_test
only compiles in wasm32 targets.
If CI ever runs cargo test
on default host without --all-targets
, add:
#![cfg_attr(target_family = "wasm", wasm_bindgen_test::wasm_bindgen_test_configure!(
run_in_browser
))]
to avoid accidental omissions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to do this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@findolor I understand! Thanks for confirming that the current test configuration works well for your setup. I'll remember this for future reviews of your codebase.
(_/)
( •_•)
/ >🧠
✏️ Learnings added
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1715
File: crates/js_api/src/common/mod.rs:111-118
Timestamp: 2025-04-30T09:28:36.848Z
Learning: In the rain.orderbook repository, the WASM tests are already properly configured with conditional compilation using `#[cfg(target_family = "wasm")]` and `#[cfg(not(target_family = "wasm"))]`, and don't require additional `wasm_bindgen_test_configure!(run_in_browser)` directives.
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.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Tsify)] | ||
pub struct AddOrderCalldata(#[tsify(type = "string")] Bytes); | ||
impl_wasm_traits!(AddOrderCalldata); | ||
|
||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Tsify)] | ||
pub struct RemoveOrderCalldata(#[tsify(type = "string")] Bytes); | ||
impl_wasm_traits!(RemoveOrderCalldata); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Expose the inner Bytes
via Deref
to avoid dot-zero (.0
) access
Most call-sites (including your own tests) reach into the tuple struct with calldata.0
.
Implementing Deref<Target = Bytes>
(or adding an as_ref()
helper) yields cleaner ergonomics:
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Tsify)]
pub struct AddOrderCalldata(#[tsify(type = "string")] Bytes);
impl_wasm_traits!(AddOrderCalldata);
+
+impl std::ops::Deref for AddOrderCalldata {
+ type Target = Bytes;
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
Apply the same pattern to RemoveOrderCalldata
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to do this for now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@findolor Understood! I'll respect your decision not to implement the Deref
trait for these structs at this time. The current approach with .0
access works fine as is.
/// Get addOrder() calldata from a given dotrain text and deployment key from its frontmatter | ||
#[wasm_export( | ||
js_name = "getAddOrderCalldata", | ||
unchecked_return_type = "AddOrderCalldata" | ||
)] | ||
pub async fn get_add_order_calldata( | ||
dotrain: &str, | ||
deployment: &str, | ||
) -> Result<AddOrderCalldata, Error> { | ||
let config: Config = parse_frontmatter(dotrain.to_string()).await?.try_into()?; | ||
let deployment_ref = config | ||
.deployments | ||
.get(deployment) | ||
.ok_or(Error::UndefinedDeployment)?; | ||
let add_order_args = | ||
AddOrderArgs::new_from_deployment(dotrain.to_string(), deployment_ref.deref().clone()) | ||
.await?; | ||
|
||
let tx_args = TransactionArgs { | ||
rpc_url: deployment_ref.scenario.deployer.network.rpc.to_string(), | ||
..Default::default() | ||
}; | ||
let calldata = add_order_args.get_add_order_calldata(tx_args).await?; | ||
Ok(AddOrderCalldata(Bytes::copy_from_slice(&calldata))) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Potential extra allocation – reuse the existing Bytes
get_add_order_calldata
clones deployment_ref
and then copies the calldata again into a new Bytes
.
If AddOrderArgs::get_add_order_calldata
already returns a Bytes
(or something convertible without copy) you can eliminate the copy_from_slice
:
- let calldata = add_order_args.get_add_order_calldata(tx_args).await?;
- Ok(AddOrderCalldata(Bytes::copy_from_slice(&calldata)))
+ let calldata: Bytes = add_order_args
+ .get_add_order_calldata(tx_args)
+ .await?
+ .into();
+ Ok(AddOrderCalldata(calldata))
(May require tweaking trait bounds.)
📝 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.
/// Get addOrder() calldata from a given dotrain text and deployment key from its frontmatter | |
#[wasm_export( | |
js_name = "getAddOrderCalldata", | |
unchecked_return_type = "AddOrderCalldata" | |
)] | |
pub async fn get_add_order_calldata( | |
dotrain: &str, | |
deployment: &str, | |
) -> Result<AddOrderCalldata, Error> { | |
let config: Config = parse_frontmatter(dotrain.to_string()).await?.try_into()?; | |
let deployment_ref = config | |
.deployments | |
.get(deployment) | |
.ok_or(Error::UndefinedDeployment)?; | |
let add_order_args = | |
AddOrderArgs::new_from_deployment(dotrain.to_string(), deployment_ref.deref().clone()) | |
.await?; | |
let tx_args = TransactionArgs { | |
rpc_url: deployment_ref.scenario.deployer.network.rpc.to_string(), | |
..Default::default() | |
}; | |
let calldata = add_order_args.get_add_order_calldata(tx_args).await?; | |
Ok(AddOrderCalldata(Bytes::copy_from_slice(&calldata))) | |
} | |
/// Get addOrder() calldata from a given dotrain text and deployment key from its frontmatter | |
#[wasm_export( | |
js_name = "getAddOrderCalldata", | |
unchecked_return_type = "AddOrderCalldata" | |
)] | |
pub async fn get_add_order_calldata( | |
dotrain: &str, | |
deployment: &str, | |
) -> Result<AddOrderCalldata, Error> { | |
let config: Config = parse_frontmatter(dotrain.to_string()).await?.try_into()?; | |
let deployment_ref = config | |
.deployments | |
.get(deployment) | |
.ok_or(Error::UndefinedDeployment)?; | |
let add_order_args = | |
AddOrderArgs::new_from_deployment(dotrain.to_string(), deployment_ref.deref().clone()) | |
.await?; | |
let tx_args = TransactionArgs { | |
rpc_url: deployment_ref.scenario.deployer.network.rpc.to_string(), | |
..Default::default() | |
}; | |
- let calldata = add_order_args.get_add_order_calldata(tx_args).await?; | |
- Ok(AddOrderCalldata(Bytes::copy_from_slice(&calldata))) | |
+ let calldata: Bytes = add_order_args | |
+ .get_add_order_calldata(tx_args) | |
+ .await? | |
+ .into(); | |
+ Ok(AddOrderCalldata(calldata)) | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is okay in our case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@findolor Understood! I'll respect your preference to keep the current implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
Cargo.toml
(1 hunks)crates/js_api/src/gui/state_management.rs
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (16)
- GitHub Check: test
- GitHub Check: standard-tests (ubuntu-latest, rainix-sol-legal)
- GitHub Check: standard-tests (ubuntu-latest, rainix-wasm-test)
- GitHub Check: standard-tests (ubuntu-latest, test-js-bindings)
- GitHub Check: standard-tests (ubuntu-latest, rainix-sol-artifacts)
- GitHub Check: standard-tests (ubuntu-latest, rainix-sol-test)
- GitHub Check: standard-tests (ubuntu-latest, rainix-wasm-artifacts)
- GitHub Check: standard-tests (ubuntu-latest, rainix-sol-static)
- GitHub Check: standard-tests (ubuntu-latest, rainix-rs-static)
- GitHub Check: standard-tests (ubuntu-latest, rainix-rs-artifacts, true)
- GitHub Check: standard-tests (ubuntu-latest, ob-rs-test, true)
- GitHub Check: build-tauri (ubuntu-22.04, true)
- GitHub Check: test
- GitHub Check: Deploy-Preview
- GitHub Check: git-clean
- GitHub Check: test
🔇 Additional comments (1)
crates/js_api/src/gui/state_management.rs (1)
293-293
: Restrict js_sys imports to test scope
Great refactor: movinguse js_sys::{eval, Reflect};
into the#[cfg(test)]
module confines unsafe/interpreter‐specific APIs to tests only, reducing surface for runtime issues in production.
@@ -53,7 +53,7 @@ test-context = "0.3.0" | |||
portpicker = "0.1.1" | |||
rain-erc = { git = "https://github.com/rainlanguage/rain.erc", rev = "0106e645ebd49334addc698c5aad9a85370eb54d" } | |||
rain-error-decoding = { git = "https://github.com/rainlanguage/rain.error", rev = "72d9577fdaf7135113847027ba951f9a43b41827" } | |||
wasm-bindgen-utils = "0.0.7" | |||
wasm-bindgen-utils = { git = "https://github.com/rainlanguage/rain.wasm", rev = "4379d24a671742a58ec5cdab2c39fecbda59619d" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Use a tagged release for wasm-bindgen-utils
to improve reproducibility
Direct Git commit references can bypass Cargo’s registry caching, slow down CI, and make builds less predictable. If there’s a published version or a stable tag for wasm-bindgen-utils
, prefer using:
wasm-bindgen-utils = "0.x.y"
or
wasm-bindgen-utils = { git = "https://github.com/rainlanguage/rain.wasm", tag = "v0.x.y" }
Otherwise, pinning a tag instead of a raw commit hash communicates stability and intent.
Verify the pinned commit exists
Run the following script to ensure the SHA is valid:
🏁 Script executed:
#!/bin/bash
git ls-remote https://github.com/rainlanguage/rain.wasm \
| grep 4379d24a671742a58ec5cdab2c39fecbda59619d \
|| echo "ERROR: Commit not found!"
Length of output: 164
Invalid Git commit for wasm-bindgen-utils
– please fix
The revision 4379d24a671742a58ec5cdab2c39fecbda59619d
wasn’t found in the rain.wasm
repository. Update Cargo.toml to one of the following:
- A published crate version
wasm-bindgen-utils = "0.x.y"
- A valid Git tag
wasm-bindgen-utils = { git = "https://github.com/rainlanguage/rain.wasm", tag = "v0.x.y" }
- A corrected commit SHA that actually exists in the remote
git ls-remote https://github.com/rainlanguage/rain.wasm \ | grep <correct-sha> \ || echo "ERROR: Commit not found!"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can stay for now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@findolor Acknowledged. I'll leave the Git dependency reference as is for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (1)
crates/js_api/src/common/mod.rs (1)
15-22
: (Repeat) Optional ergonomic helper still missingThe
.0
field access onAddOrderCalldata
/RemoveOrderCalldata
remains slightly clunky for downstream users. ImplementingDeref<Target = Bytes>
(or anas_ref()
method) would remove that friction.I’m not reopening the discussion—just documenting that the earlier suggestion hasn’t been adopted.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
crates/common/src/lib.rs
(1 hunks)crates/js_api/src/common/mod.rs
(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
crates/js_api/src/common/mod.rs (1)
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1715
File: crates/js_api/src/common/mod.rs:111-118
Timestamp: 2025-04-30T09:28:36.848Z
Learning: In the rain.orderbook repository, the WASM tests are already properly configured with conditional compilation using `#[cfg(target_family = "wasm")]` and `#[cfg(not(target_family = "wasm"))]`, and don't require additional `wasm_bindgen_test_configure!(run_in_browser)` directives.
⏰ Context from checks skipped due to timeout of 90000ms (16)
- GitHub Check: git-clean
- GitHub Check: test
- GitHub Check: standard-tests (ubuntu-latest, test-js-bindings)
- GitHub Check: standard-tests (ubuntu-latest, rainix-sol-legal)
- GitHub Check: standard-tests (ubuntu-latest, rainix-wasm-artifacts)
- GitHub Check: standard-tests (ubuntu-latest, rainix-wasm-test)
- GitHub Check: test
- GitHub Check: standard-tests (ubuntu-latest, rainix-rs-static)
- GitHub Check: standard-tests (ubuntu-latest, rainix-sol-artifacts)
- GitHub Check: standard-tests (ubuntu-latest, ob-rs-test, true)
- GitHub Check: standard-tests (ubuntu-latest, rainix-sol-static)
- GitHub Check: standard-tests (ubuntu-latest, rainix-rs-artifacts, true)
- GitHub Check: standard-tests (ubuntu-latest, rainix-sol-test)
- GitHub Check: build-tauri (ubuntu-22.04, true)
- GitHub Check: Deploy-Preview
- GitHub Check: test
🔇 Additional comments (1)
crates/common/src/lib.rs (1)
23-24
: Conditional compilation fortest_helpers
successfully re-instatedRe-applying the
#[cfg(test)]
gate keeps test-only utilities out of release builds and public docs, addressing the concern raised in the earlier review.
pub async fn get_remove_order_calldata(order: SgOrder) -> Result<RemoveOrderCalldata, Error> { | ||
let remove_order_args = RemoveOrderArgs { order }; | ||
let calldata = remove_order_args.get_rm_order_calldata().await?; | ||
Ok(RemoveOrderCalldata(Bytes::copy_from_slice(&calldata))) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Accept SgOrder
by reference to avoid an unnecessary move
get_remove_order_calldata
consumes the entire SgOrder
, which can be large. The function only needs read-only access, so taking &SgOrder
(or impl Into<SgOrder>
) avoids an extra move/clone at the call-site and keeps the API symmetric with get_add_order_calldata
.
- pub async fn get_remove_order_calldata(order: SgOrder) -> Result<RemoveOrderCalldata, Error> {
- let remove_order_args = RemoveOrderArgs { order };
+ pub async fn get_remove_order_calldata(order: &SgOrder) -> Result<RemoveOrderCalldata, Error> {
+ let remove_order_args = RemoveOrderArgs { order: order.clone() };
If RemoveOrderArgs
can own or borrow, consider adding impl<'a> From<&'a SgOrder> for RemoveOrderArgs
to eliminate the clone.
🏁 Script executed:
#!/bin/bash
set -e
# 1. Check signatures for add/remove order calldata functions
echo "get_add_order_calldata signature:"
rg -n "get_add_order_calldata" -C2 crates/js_api/src/common/mod.rs
echo
echo "get_remove_order_calldata signature:"
rg -n "get_remove_order_calldata" -C2 crates/js_api/src/common/mod.rs
# 2. Inspect the RemoveOrderArgs and AddOrderArgs definitions
echo
echo "struct RemoveOrderArgs:"
rg -n "struct RemoveOrderArgs" -C2 crates/js_api/src/common/mod.rs
echo
echo "struct AddOrderArgs:"
rg -n "struct AddOrderArgs" -C2 crates/js_api/src/common/mod.rs
# 3. Locate SgOrder and see if it derives Clone
echo
echo "struct SgOrder:"
rg -n "struct SgOrder" -C2
echo
echo "Clone derive for SgOrder:"
rg -n "derive.*Clone" -C2
Length of output: 1961
🏁 Script executed:
#!/bin/bash
set -e
echo "1. Locate RemoveOrderArgs definition"
rg -n "struct RemoveOrderArgs" -C5
echo
echo "2. Locate AddOrderArgs definition"
rg -n "struct AddOrderArgs" -C5
echo
echo "3. Locate SgOrder definition"
rg -n "struct SgOrder" -C5
echo
echo "4. Check for Clone derive on SgOrder"
rg -n "derive.*Clone" -C5
echo
echo "5. Check for manual Clone impl on SgOrder"
rg -n "impl Clone for SgOrder" -C5
Length of output: 92262
Use a reference for SgOrder
in get_remove_order_calldata
To mirror get_add_order_calldata
(which takes &str
) and avoid forcing callers to give up ownership of potentially large SgOrder
, change the signature to take &SgOrder
and clone internally:
--- a/crates/js_api/src/common/mod.rs
+++ b/crates/js_api/src/common/mod.rs
@@ -100,7 +100,7 @@
#[wasm_bindgen_test]
async fn test_get_remove_order_calldata() { /* … */ }
-pub async fn get_remove_order_calldata(order: SgOrder) -> Result<RemoveOrderCalldata, Error> {
+pub async fn get_remove_order_calldata(order: &SgOrder) -> Result<RemoveOrderCalldata, Error> {
// clone here instead of moving the caller’s `SgOrder`
- let remove_order_args = RemoveOrderArgs { order };
+ let remove_order_args = RemoveOrderArgs { order: order.clone() };
let calldata = remove_order_args.get_rm_order_calldata().await?;
Ok(RemoveOrderCalldata(Bytes::copy_from_slice(&calldata)))
}
– Since SgOrder: Clone
, this only incurs a single clone and keeps the API symmetric.
– To eliminate even that explicit clone, add in crates/common/src/remove_order.rs
:
impl<'a> From<&'a SgOrder> for RemoveOrderArgs {
fn from(order: &SgOrder) -> Self {
RemoveOrderArgs { order: order.clone() }
}
}
Then you can simplify the call site to:
let remove_order_args: RemoveOrderArgs = order.into();
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to do this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@findolor Understood! I'll respect your decision on keeping the current implementation with SgOrder
passed by value.
🐰 nods in understanding
✏️ Learnings added
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1715
File: crates/js_api/src/common/mod.rs:101-105
Timestamp: 2025-04-30T10:32:53.857Z
Learning: In the rain.orderbook project, the `get_remove_order_calldata` function takes `SgOrder` by value rather than by reference, as per maintainer preference.
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.
If you found this review helpful, would you consider giving us a shout-out on X?
Thank you for using CodeRabbit!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
crates/js_api/src/common/mod.rs
(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
crates/js_api/src/common/mod.rs (2)
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1715
File: crates/js_api/src/common/mod.rs:111-118
Timestamp: 2025-04-30T09:28:36.848Z
Learning: In the rain.orderbook repository, the WASM tests are already properly configured with conditional compilation using `#[cfg(target_family = "wasm")]` and `#[cfg(not(target_family = "wasm"))]`, and don't require additional `wasm_bindgen_test_configure!(run_in_browser)` directives.
Learnt from: findolor
PR: rainlanguage/rain.orderbook#1715
File: crates/js_api/src/common/mod.rs:101-105
Timestamp: 2025-04-30T10:32:53.857Z
Learning: In the rain.orderbook project, the `get_remove_order_calldata` function takes `SgOrder` by value rather than by reference, as per maintainer preference.
⏰ Context from checks skipped due to timeout of 90000ms (4)
- GitHub Check: standard-tests (ubuntu-latest, rainix-rs-static)
- GitHub Check: standard-tests (ubuntu-latest, test-js-bindings)
- GitHub Check: standard-tests (ubuntu-latest, rainix-sol-test)
- GitHub Check: standard-tests (ubuntu-latest, rainix-sol-static)
use std::ops::Deref; | ||
use thiserror::Error; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Remove needless Deref
import and explicit .deref()
call
deployment_ref
is already a plain &Deployment
– cloning it is sufficient.
Importing std::ops::Deref
and calling deployment_ref.deref()
only adds noise.
- use std::ops::Deref;
...
- AddOrderArgs::new_from_deployment(dotrain_owned.clone(), deployment_ref.deref().clone())
+ AddOrderArgs::new_from_deployment(dotrain_owned.clone(), deployment_ref.clone())
This keeps the code concise and eliminates an otherwise-unused import.
Also applies to: 85-86
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to do this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@findolor Understood, I'll respect your preference to keep the code as is with the Deref
import and explicit .deref()
call. Thanks for reviewing my suggestion!
pub async fn get_add_order_calldata( | ||
dotrain: &str, | ||
deployment: &str, | ||
) -> Result<AddOrderCalldata, Error> { | ||
let config: Config = parse_frontmatter(dotrain.to_string()).await?.try_into()?; | ||
let deployment_ref = config | ||
.deployments | ||
.get(deployment) | ||
.ok_or(Error::UndefinedDeployment)?; | ||
let add_order_args = | ||
AddOrderArgs::new_from_deployment(dotrain.to_string(), deployment_ref.deref().clone()) | ||
.await?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Avoid cloning dotrain
twice – keep a single owned copy
dotrain.to_string()
is performed twice, allocating two identical String
s.
Taking ownership once and re-using it trims a small but unnecessary cost and simplifies the call-sites.
- let config: Config = parse_frontmatter(dotrain.to_string()).await?.try_into()?;
+ let dotrain_owned = dotrain.to_owned();
+ let config: Config = parse_frontmatter(dotrain_owned.clone()).await?.try_into()?;
...
- let add_order_args =
- AddOrderArgs::new_from_deployment(dotrain.to_string(), deployment_ref.clone())
+ let add_order_args =
+ AddOrderArgs::new_from_deployment(dotrain_owned, deployment_ref.clone())
(If parse_frontmatter
consumes its argument you can move rather than clone in the first call.)
Committable suggestion skipped: line range outside the PR's diff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to do this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@findolor Understood, I'll back off that suggestion. The current approach is perfectly fine.
Motivation
See issue: #1621
Solution
Checks
By submitting this for review, I'm confirming I've done the following:
[ ] included screenshots (if this involves a front-end change)fix #1621
Summary by CodeRabbit
New Features
Refactor
wasm-bindgen-utils
to use a specific Git commit.Bug Fixes
Tests
Chores