Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ nix develop -c cargo test --workspace
If the end-of-session gate fails during `./prep-all.sh`, run these steps sequentially so dependencies still build:
```bash
nix develop -c forge install
nix develop -c bash -c '(cd lib/rain.interpreter && rainix-sol-prelude && rainix-rs-prelude && i9r-prelude)'
nix develop -c bash -c '(cd lib/rain.interpreter && rainix-sol-prelude && rainix-rs-prelude && rainlang-prelude)'
nix develop -c bash -c '(cd lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.math.float && rainix-sol-prelude && rainix-rs-prelude)'
nix develop -c bash -c '(cd lib/rain.interpreter/lib/rain.metadata && rainix-sol-prelude && rainix-rs-prelude)'
nix develop -c rainix-sol-prelude && nix develop -c rainix-rs-prelude && nix develop -c raindex-prelude
Expand All @@ -79,4 +79,4 @@ nix develop -c npm run build -w @rainlanguage/webapp

Goal: all CI checks in `.github/workflows` pass. Be patient with long builds/tests and never commit with failing lint/tests.



117 changes: 60 additions & 57 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ dotrain-lsp = "6.0.1-alpha.24"
rain-metadata = { path = "lib/rain.interpreter/lib/rain.metadata/crates/cli" }
rain-metadata-bindings = { path = "lib/rain.interpreter/lib/rain.metadata/crates/bindings" }
rain-metaboard-subgraph = { path = "lib/rain.interpreter/lib/rain.metadata/crates/metaboard" }
rain_interpreter_bindings = { path = "lib/rain.interpreter/crates/bindings" }
rain_interpreter_dispair = { path = "lib/rain.interpreter/crates/dispair" }
rain_interpreter_parser = { path = "lib/rain.interpreter/crates/parser" }
rain-interpreter-eval = { path = "lib/rain.interpreter/crates/eval" }
rain_interpreter_bindings = { package = "rainlang_bindings", path = "lib/rain.interpreter/crates/bindings" }
rain_interpreter_dispair = { package = "rainlang_dispair", path = "lib/rain.interpreter/crates/dispair" }
rain_interpreter_parser = { package = "rainlang_parser", path = "lib/rain.interpreter/crates/parser" }
rain-interpreter-eval = { package = "rainlang-eval", path = "lib/rain.interpreter/crates/eval" }
csv = "1.3.0"
insta = { version = "1.34.0" }
proptest = "1.4.0"
Expand Down
2 changes: 1 addition & 1 deletion ai_commands/sdk-documentation-update.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,4 @@ What to return

Notes
- This repo uses a macro named `wasm_export` in `crates/js_api` to define JS-visible APIs and attach TypeScript-specific metadata (`js_name`, `unchecked_return_type`, `param_description`, `return_description`, `preserve_js_class`). Treat those attributes as the contract for the generated TypeScript surface.
- Some examples in README demonstrate end-to-end flows (e.g., GUI setup via `DotrainOrderGui`, order hash/calldata helpers). Prefer aligning those with current tests under `packages/orderbook/test/js_api` to avoid drift.
- Some examples in README demonstrate end-to-end flows (e.g., builder setup via `RaindexOrderBuilder`, order hash/calldata helpers). Prefer aligning those with current tests under `packages/orderbook/test/js_api` to avoid drift.
10 changes: 5 additions & 5 deletions crates/bindings/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ File Layout
- Cargo.toml: Declares the crate `rain_orderbook_bindings`. Key deps: `alloy` (codegen + types + RPC), `serde` (Serialize/Deserialize), `tower` (layers), `url`, `thiserror`. For WASM builds it uses `wasm-bindgen-utils` and `wasm-bindgen-test` for tests.
- src/lib.rs: Declares contract bindings using Alloy’s `sol!` macro and re‑exports internal modules. Conditionally includes WASM modules.
- src/provider.rs: Builds a read‑only provider with multi‑RPC fallback and sensible default request fillers.
- src/js_api.rs (wasm only): JS/WASM interop. Implements wasm conversion traits and custom TypeScript interfaces for selected ABI types used in the GUI.
- src/js_api.rs (wasm only): JS/WASM interop. Implements wasm conversion traits and custom TypeScript interfaces for selected ABI types used in the order builder.
- src/wasm_traits.rs (wasm only): Utility trait to convert JS `BigInt` to `U256` with negative/overflow handling plus tests.

Generated Solidity Bindings (Alloy `sol!`)
Expand All @@ -34,7 +34,7 @@ Generated Solidity Bindings (Alloy `sol!`)

- Derives and defaults:
- `all_derives = true` enables useful traits on generated types, including `Clone`, `Debug`, `Default`, `Eq`, `PartialEq`, and more, which the codebase relies on (e.g., `OrderV4::default()`).
- `extra_derives(serde::Serialize, serde::Deserialize)` ensures all ABI types can be serialized to/from JSON, which is critical for CLI/GUI I/O and WASM interop.
- `extra_derives(serde::Serialize, serde::Deserialize)` ensures all ABI types can be serialized to/from JSON, which is critical for CLI/builder I/O and WASM interop.

ABI Source of Truth
- The referenced JSON files under `out/` are produced by Foundry (`forge build`). If ABIs change, re‑build the contracts so `out/.../*.json` stays in sync. The `sol!` macro reads these on compile.
Expand All @@ -59,7 +59,7 @@ Provider Utilities (`src/provider.rs`)
WASM and JS Interop
- Conditional compilation: `src/js_api.rs` and `src/wasm_traits.rs` are compiled only for `target_family = "wasm"`.

- `src/js_api.rs` bridges key ABI types to predictable TypeScript shapes for the GUI, using the workspace’s `wasm-bindgen-utils` macros:
- `src/js_api.rs` bridges key ABI types to predictable TypeScript shapes for the order builder, using the workspace’s `wasm-bindgen-utils` macros:
- `impl_wasm_traits!(T)` implements glue code to convert between Rust and JS values (e.g., Serde + wasm-bindgen interop) for the given type.
- `impl_custom_tsify!(T, "…TS interface…")` pins the exact TypeScript surface for WASM consumers. This avoids relying on auto‑generated typings that may drift with upstream changes.

Expand Down Expand Up @@ -93,7 +93,7 @@ How This Crate Is Used Elsewhere
- Common utilities (`crates/common`):
- Uses ABI‑generated call structs (e.g., `deposit3Call`, `withdraw3Call`, `removeOrder3Call`, `IERC20::approveCall`) to build calldata for transactions.
- JS API (`crates/js_api`):
- Builds GUI calldata for approvals/deposits/add‑order and uses call structs like `OrderBook::multicallCall` without needing on‑chain RPC instance helpers.
- Builds order builder calldata for approvals/deposits/add‑order and uses call structs like `OrderBook::multicallCall` without needing on‑chain RPC instance helpers.
- CLI (`crates/cli`):
- Consumes ABI struct types such as `OrderV4` and `IOV2` to construct orders from user inputs.

Expand Down Expand Up @@ -132,5 +132,5 @@ Limitations and Notes
- `AnyNetwork` provider: Consumers are responsible for ensuring the supplied RPCs point to the intended chain.

Updating Bindings
- Modify the Solidity contracts as needed, run `nix develop -c forge build`, then rebuild Rust. If new structs/functions are added to the ABIs, they will appear under the corresponding Rust modules after recompilation. Add/update WASM TS interfaces in `src/js_api.rs` as needed for GUI usage.
- Modify the Solidity contracts as needed, run `nix develop -c forge build`, then rebuild Rust. If new structs/functions are added to the ABIs, they will appear under the corresponding Rust modules after recompilation. Add/update WASM TS interfaces in `src/js_api.rs` as needed for order builder usage.

3 changes: 3 additions & 0 deletions crates/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ eyre.workspace = true
rain-math-float.workspace = true
tower.workspace = true
flate2 = "1.0.34"
base64 = "0.22.1"
bincode = "1.3.3"
sha2 = "0.10.8"
itertools = { workspace = true }
async-trait = { workspace = true }
web-sys = { version = "0.3", features = ["Window", "Navigator", "console"] }
Expand Down
40 changes: 21 additions & 19 deletions crates/common/src/add_order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use rain_interpreter_eval::{
};
use rain_interpreter_parser::{Parser2, ParserError, ParserV2};
use rain_metadata::{
types::dotrain::gui_state_v1::DotrainGuiStateV1,
types::dotrain::order_builder_state_v1::OrderBuilderStateV1,
types::raindex_signed_context_oracle::RaindexSignedContextOracleV1, ContentEncoding,
ContentLanguage, ContentType, Error as RainMetaError, KnownMagic, RainMetaDocumentV1Item,
};
Expand Down Expand Up @@ -327,11 +327,11 @@ impl AddOrderArgs {
Some(meta_docs) => {
match meta_docs
.iter()
.find(|document| document.magic == KnownMagic::DotrainGuiStateV1)
.find(|document| document.magic == KnownMagic::OrderBuilderStateV1)
{
Some(doc) => {
let gui_state = DotrainGuiStateV1::try_from(doc.clone())?;
let subject_hash = gui_state.dotrain_hash();
let builder_state = OrderBuilderStateV1::try_from(doc.clone())?;
let subject_hash = builder_state.dotrain_hash();
let meta_document = RainMetaDocumentV1Item {
payload: ByteBuf::from(self.dotrain.as_bytes()),
magic: KnownMagic::DotrainSourceV1,
Expand Down Expand Up @@ -532,7 +532,7 @@ price: 2e18;
fn test_try_generate_meta_with_additional_meta_filters_reserved() {
let dotrain_body = "/* test */".to_string();
let dotrain_hash = DotrainSourceV1(dotrain_body.clone()).hash();
let gui_state = DotrainGuiStateV1 {
let builder_state = OrderBuilderStateV1 {
dotrain_hash,
field_values: BTreeMap::new(),
deposits: BTreeMap::new(),
Expand All @@ -552,7 +552,7 @@ price: 2e18;
// Should be filtered out
RainMetaDocumentV1Item::from(DotrainSourceV1("ignored-dotrain".to_string())),
// Should be retained
RainMetaDocumentV1Item::try_from(gui_state.clone()).unwrap(),
RainMetaDocumentV1Item::try_from(builder_state.clone()).unwrap(),
];

let args = AddOrderArgs {
Expand All @@ -570,23 +570,23 @@ price: 2e18;
// Rainlang meta is always present and should match the composed rainlang payload
assert_eq!(decoded[0].magic, KnownMagic::RainlangSourceV1);
assert_eq!(decoded[0].payload.as_ref(), "rainlang-body".as_bytes());
// Only the GUI state from additional meta should remain (reserved magics filtered)
// Only the builder state from additional meta should remain (reserved magics filtered)
assert_eq!(decoded.len(), 2);
let gui_meta = decoded
let builder_meta = decoded
.iter()
.find(|item| item.magic == KnownMagic::DotrainGuiStateV1)
.expect("gui state meta not found");
.find(|item| item.magic == KnownMagic::OrderBuilderStateV1)
.expect("builder state meta not found");
assert_eq!(
DotrainGuiStateV1::try_from(gui_meta.clone()).unwrap(),
gui_state
OrderBuilderStateV1::try_from(builder_meta.clone()).unwrap(),
builder_state
);
}

#[test]
fn test_try_into_emit_meta_call_with_gui_state() {
fn test_try_into_emit_meta_call_with_builder_state() {
let dotrain_body = "/* dotrain template */".to_string();
let dotrain_source = DotrainSourceV1(dotrain_body.clone());
let gui_state = DotrainGuiStateV1 {
let builder_state = OrderBuilderStateV1 {
dotrain_hash: dotrain_source.hash(),
field_values: BTreeMap::new(),
deposits: BTreeMap::new(),
Expand All @@ -600,7 +600,9 @@ price: 2e18;
outputs: vec![],
bindings: HashMap::new(),
rainlang: Address::default(),
additional_meta: Some(vec![RainMetaDocumentV1Item::try_from(gui_state).unwrap()]),
additional_meta: Some(vec![
RainMetaDocumentV1Item::try_from(builder_state).unwrap()
]),
};

let emit_call = args
Expand All @@ -616,10 +618,10 @@ price: 2e18;
}

#[test]
fn test_try_into_emit_meta_call_invalid_gui_state_payload() {
let invalid_gui_state = RainMetaDocumentV1Item {
fn test_try_into_emit_meta_call_invalid_builder_state_payload() {
let invalid_builder_state = RainMetaDocumentV1Item {
payload: ByteBuf::from(vec![1, 2, 3]),
magic: KnownMagic::DotrainGuiStateV1,
magic: KnownMagic::OrderBuilderStateV1,
content_type: ContentType::OctetStream,
content_encoding: ContentEncoding::None,
content_language: ContentLanguage::None,
Expand All @@ -630,7 +632,7 @@ price: 2e18;
outputs: vec![],
bindings: HashMap::new(),
rainlang: Address::default(),
additional_meta: Some(vec![invalid_gui_state]),
additional_meta: Some(vec![invalid_builder_state]),
};

let err = args.try_into_emit_meta_call().unwrap_err();
Expand Down
Loading
Loading