Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
80031ce
add support for wasm with cairo 1
FrancoGiachetta Sep 30, 2025
056e966
correct Cargo.lock
FrancoGiachetta Sep 30, 2025
5540f96
fix workflow
FrancoGiachetta Oct 1, 2025
45eaa2a
fix workflow
FrancoGiachetta Oct 1, 2025
ebc6cab
add std feature for cairo1-run
FrancoGiachetta Oct 1, 2025
43a3c72
use a different program as an example
FrancoGiachetta Oct 1, 2025
709abe8
fmt + fix workflow
FrancoGiachetta Oct 1, 2025
02d1fea
update changelog
FrancoGiachetta Oct 1, 2025
1972c3e
use default features for cairo 1
FrancoGiachetta Oct 1, 2025
6d048d9
try fix ci
FrancoGiachetta Oct 1, 2025
d9a1438
compile example
FrancoGiachetta Oct 1, 2025
00c29f3
use cairo 1 compiler
FrancoGiachetta Oct 1, 2025
1d0fc9b
try to fix ci
FrancoGiachetta Oct 1, 2025
0356219
correct compiler command
FrancoGiachetta Oct 1, 2025
597ebac
fetch program from cache
FrancoGiachetta Oct 1, 2025
c7bb8c8
try fix ci
FrancoGiachetta Oct 1, 2025
31f833c
save in cache
FrancoGiachetta Oct 1, 2025
0e09763
add sierra path to CAIRO_PROGRAMS_PATH
FrancoGiachetta Oct 1, 2025
2af23d2
try fix
FrancoGiachetta Oct 1, 2025
32a2f6c
change hashFiles function
FrancoGiachetta Oct 2, 2025
b0cafef
make cairo1-run cli require std feature
FrancoGiachetta Oct 2, 2025
64604a6
remove unnecessary file path in hashFiles function
FrancoGiachetta Oct 2, 2025
4ae89c8
format toml
FrancoGiachetta Oct 2, 2025
0d40642
improve readme + remove todo
FrancoGiachetta Oct 2, 2025
186a862
update makefile so that make tests does not complain
FrancoGiachetta Oct 3, 2025
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
37 changes: 35 additions & 2 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ env:
cairo_programs/**/*.json
!cairo_programs/manually_compiled/*
examples/wasm-demo/src/array_sum.json
cairo_programs/cairo-1-programs/bitwise.sierra
TEST_COLLECT_COVERAGE: 1
PROPTEST_CASES: 100

Expand Down Expand Up @@ -48,6 +49,7 @@ jobs:
- cairo_test_programs
- cairo_1_test_contracts
- cairo_2_test_contracts
- wasm_cairo_1_example
name: Build Cairo programs
runs-on: ubuntu-24.04
steps:
Expand Down Expand Up @@ -90,15 +92,19 @@ jobs:
echo PATH=$PATH >> $GITHUB_ENV

- name: Install cairo 1 compiler
if: steps.cache-programs.outputs.cache-hit != 'true' && matrix.program-target == 'cairo_1_test_contracts'
if: steps.cache-programs.outputs.cache-hit != 'true' && (matrix.program-target == 'cairo_1_test_contracts' || matrix.program-target == 'wasm_cairo_1_example')
run: make build-cairo-1-compiler

- name: Install cairo 2 compiler
if: steps.cache-programs.outputs.cache-hit != 'true' && matrix.program-target == 'cairo_2_test_contracts'
run: make build-cairo-2-compiler

- name: Build Cairo 1 WASM example
if: steps.cache-programs.outputs.cache-hit != 'true' && matrix.program-target == 'wasm_cairo_1_example'
run: ./cairo1/bin/cairo-compile -r cairo_programs/cairo-1-programs/bitwise.cairo cairo_programs/cairo-1-programs/bitwise.sierra

- name: Build programs
if: steps.cache-programs.outputs.cache-hit != 'true'
if: steps.cache-programs.outputs.cache-hit != 'true' && matrix.program-target != 'wasm_cairo_1_example'
run: make -j ${{ matrix.program-target }}

# NOTE: used to reduce the amount of cache steps we need in later jobs
Expand Down Expand Up @@ -146,6 +152,12 @@ jobs:
path: ${{ env.CAIRO_PROGRAMS_PATH }}
key: cairo_2_test_contracts-cache-${{ hashFiles('cairo_programs/**/*.cairo', 'examples/wasm-demo/src/array_sum.cairo', 'Makefile', 'requirements.txt') }}
fail-on-cache-miss: true
- name: Fetch WASM Cairo 1 Example
uses: actions/cache/restore@v3
with:
path: ${{ env.CAIRO_PROGRAMS_PATH }}
key: wasm_cairo_1_example-cache-${{ hashFiles('cairo_programs/**/*.cairo', 'examples/wasm-demo/src/array_sum.cairo', 'Makefile', 'requirements.txt') }}
fail-on-cache-miss: true

- name: Merge caches
uses: actions/cache/save@v3
Expand Down Expand Up @@ -819,6 +831,27 @@ jobs:
cd examples/wasm-demo
wasm-pack build --target=web

wasm-demo-cairo1:
name: Build the wasm demo cairo1
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install uv
uses: astral-sh/setup-uv@v5

- name: Install wasm-pack dep
run: npm install -g wasm-pack

- name: Make deps
run: make deps

- name: Build wasm-demo-cairo1
run: |
./cairo1/bin/cairo-compile -r cairo_programs/cairo-1-programs/bitwise.cairo cairo_programs/cairo-1-programs/bitwise.sierra
cd examples/wasm-demo-cairo1
wasm-pack build --target=web

compare-factorial-outputs-all-layouts:
name: Compare factorial outputs for all layouts
needs: [ build-programs, build-release ]
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#### Upcoming Changes

* feat: Add support for WASM with Cairo 1 [#2216](https://github.com/lambdaclass/cairo-vm/pull/2216)

* fix: Added `cairo_1_test_contracts` and `cairo_2_test_contracts` as dependencies for `test-extensive_hints` target [#2201](https://github.com/lambdaclass/cairo-vm/pull/2201)

* breaking: Store constants in Hint Data [#2191](https://github.com/lambdaclass/cairo-vm/pull/2191)
Expand Down
13 changes: 13 additions & 0 deletions Cargo.lock

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

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ members = [
"vm",
"hint_accountant",
"examples/wasm-demo",
"examples/wasm-demo-cairo1",
"cairo1-run",
"cairo-vm-tracer",
"examples/hyper_threading",
Expand Down Expand Up @@ -89,6 +90,9 @@ lto = "fat"
# Tell `rustc` to optimize for small code size.
opt-level = "s"

[profile.release.package.wasm-demo-cairo1]
opt-level = "s"

[profile.test.package.proptest]
opt-level = 3

Expand Down
18 changes: 13 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
RELBIN:=target/release/cairo-vm-run
DBGBIN:=target/debug/cairo-vm-run

CAIRO_1_COMPILE=cairo1/bin/cairo-compile
STARKNET_COMPILE_CAIRO_1:=cairo1/bin/starknet-compile
STARKNET_SIERRA_COMPILE_CAIRO_1:=cairo1/bin/starknet-sierra-compile

Expand Down Expand Up @@ -146,6 +147,7 @@ $(PRINT_TEST_DIR)/%.json: $(PRINT_TEST_DIR)/%.cairo
# Test Cairo 1 Contracts
# ======================

CAIRO_1_PROGRAMS_TEST_DIR=cairo_programs/cairo-1-programs
CAIRO_1_CONTRACTS_TEST_DIR=cairo_programs/cairo-1-contracts
CAIRO_1_CONTRACTS_TEST_CAIRO_FILES:=$(wildcard $(CAIRO_1_CONTRACTS_TEST_DIR)/*.cairo)
CAIRO_1_COMPILED_SIERRA_CONTRACTS:=$(patsubst $(CAIRO_1_CONTRACTS_TEST_DIR)/%.cairo, $(CAIRO_1_CONTRACTS_TEST_DIR)/%.sierra, $(CAIRO_1_CONTRACTS_TEST_CAIRO_FILES))
Expand All @@ -157,6 +159,10 @@ $(CAIRO_1_CONTRACTS_TEST_DIR)/%.sierra: $(CAIRO_1_CONTRACTS_TEST_DIR)/%.cairo
$(CAIRO_1_CONTRACTS_TEST_DIR)/%.casm: $(CAIRO_1_CONTRACTS_TEST_DIR)/%.sierra
$(STARKNET_SIERRA_COMPILE_CAIRO_1) --allowed-libfuncs-list-name experimental_v0.1.0 $< $@

# This is needed so that wasm with cairo 1 doen't complain.
$(CAIRO_1_PROGRAMS_TEST_DIR)/bitwise.sierra: $(CAIRO_1_PROGRAMS_TEST_DIR)/bitwise.cairo
$(CAIRO_1_COMPILE) -r $< $@

# ======================
# Setup Cairo 1 Compiler
# ======================
Expand Down Expand Up @@ -259,6 +265,7 @@ cairo_proof_programs: $(COMPILED_PROOF_TESTS) $(COMPILED_MOD_BUILTIN_PROOF_TESTS
cairo_bench_programs: $(COMPILED_BENCHES)
cairo_1_test_contracts: $(CAIRO_1_COMPILED_CASM_CONTRACTS)
cairo_2_test_contracts: $(CAIRO_2_COMPILED_CASM_CONTRACTS)
cairo_1_program: $(CAIRO_1_PROGRAMS_TEST_DIR)/bitwise.sierra

cairo_proof_trace: $(CAIRO_TRACE_PROOF) $(CAIRO_MEM_PROOF) $(CAIRO_AIR_PUBLIC_INPUT) $(CAIRO_AIR_PRIVATE_INPUT)
cairo-vm_proof_trace: $(CAIRO_RS_TRACE_PROOF) $(CAIRO_RS_MEM_PROOF) $(CAIRO_RS_AIR_PUBLIC_INPUT) $(CAIRO_RS_AIR_PRIVATE_INPUT)
Expand All @@ -271,14 +278,14 @@ ifdef TEST_COLLECT_COVERAGE
TEST_COMMAND:=cargo llvm-cov nextest --no-report
endif

test: cairo_proof_programs cairo_test_programs cairo_1_test_contracts cairo_2_test_contracts
test: cairo_proof_programs cairo_test_programs cairo_1_test_contracts cairo_2_test_contracts cairo_1_program
$(TEST_COMMAND) --workspace --features "test_utils, cairo-1-hints"
test-no_std: cairo_proof_programs cairo_test_programs
test-no_std: cairo_proof_programs cairo_test_programs cairo_1_program
$(TEST_COMMAND) --workspace --features test_utils --no-default-features
test-wasm: cairo_proof_programs cairo_test_programs
test-wasm: cairo_proof_programs cairo_test_programs cairo_1_program
# NOTE: release mode is needed to avoid "too many locals" error
wasm-pack test --release --node vm --no-default-features
test-extensive_hints: cairo_proof_programs cairo_test_programs cairo_1_test_contracts cairo_2_test_contracts
test-extensive_hints: cairo_proof_programs cairo_test_programs cairo_1_test_contracts cairo_1_program cairo_2_test_contracts
$(TEST_COMMAND) --workspace --features "test_utils, cairo-1-hints, cairo-0-secp-hints, cairo-0-data-availability-hints, extensive_hints"

check-fmt:
Expand All @@ -289,7 +296,7 @@ clippy:
cargo clippy --workspace --all-features --benches --examples --tests -- -D warnings
cargo clippy --manifest-path fuzzer/Cargo.toml --all-targets

coverage: cairo_proof_programs cairo_test_programs cairo_1_test_contracts cairo_2_test_contracts
coverage: cairo_proof_programs cairo_test_programs cairo_1_test_contracts cairo_1_program cairo_2_test_contracts
cargo llvm-cov --html --workspace --features "test_utils, cairo-1-hints"

coverage-clean:
Expand Down Expand Up @@ -365,6 +372,7 @@ clean:
rm -f $(PRINT_TEST_DIR)/*.json
rm -f $(CAIRO_1_CONTRACTS_TEST_DIR)/*.sierra
rm -f $(CAIRO_1_CONTRACTS_TEST_DIR)/*.casm
rm -f $(CAIRO_1_PROGRAMS_TEST_DIR)/bitwise.sierra
rm -f $(TEST_PROOF_DIR)/*.cairo
rm -f $(CAIRO_2_CONTRACTS_TEST_DIR)/*.sierra
rm -f $(CAIRO_2_CONTRACTS_TEST_DIR)/*.casm
Expand Down
10 changes: 9 additions & 1 deletion cairo1-run/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ keywords.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
cairo-vm = { workspace = true, features = ["std", "cairo-1-hints", "clap"] }
cairo-vm = { workspace = true, features = ["cairo-1-hints", "clap"] }
serde_json = { workspace = true }

cairo-lang-sierra-type-size = { version = "2.12.0-dev.0", default-features = false }
Expand All @@ -26,6 +26,14 @@ assert_matches = "1.5.0"
rstest = "0.17.0"
num-traits = { version = "0.2", default-features = false }
num-bigint.workspace = true
getrandom = { version = "0.2.16", features = ["js"]}

[features]
default = ["std"]
mod_builtin = ["cairo-vm/mod_builtin"]
std = ["cairo-vm/std"]

[[bin]]
name = "cairo1-run"
path = "./src/main.rs"
required-features = ["std"]
4 changes: 2 additions & 2 deletions cairo1-run/src/cairo_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ use cairo_vm::{
hint_processor::cairo_1_hint_processor::hint_processor::Cairo1HintProcessor,
math_utils::signed_felt,
serde::deserialize_program::{ApTracking, FlowTrackingData, HintParams, ReferenceManager},
stdlib::{collections::HashMap, iter::Peekable},
types::{
builtin_name::BuiltinName, layout::CairoLayoutParams, layout_name::LayoutName,
program::Program, relocatable::MaybeRelocatable,
Expand All @@ -52,7 +53,6 @@ use cairo_vm::{
use itertools::{chain, Itertools};
use num_bigint::{BigInt, Sign};
use num_traits::{cast::ToPrimitive, Zero};
use std::{collections::HashMap, iter::Peekable};

/// Representation of a cairo argument
/// Can consist of a single Felt or an array of Felts
Expand Down Expand Up @@ -616,7 +616,7 @@ fn create_entry_code(
} else if generic_ty == &GasBuiltinType::ID {
// Load initial gas
casm_build_extend! {ctx,
const initial_gas = 9999999999999_usize;
const initial_gas = 9999999999999_u64;
tempvar gas = initial_gas;
};
} else {
Expand Down
31 changes: 31 additions & 0 deletions examples/wasm-demo-cairo1/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[package]
name = "wasm-demo-cairo1"
description = "A demo using cairo-vm in a WASM environment"
version.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
readme = "README.md"
keywords.workspace = true
publish = false

[lib]
crate-type = ["cdylib", "rlib"]

[features]
default = ["console_error_panic_hook"]

[dependencies]
wasm-bindgen = "0.2.100"

# The `console_error_panic_hook` crate provides better debugging of panics by
# logging them with `console.error`. This is great for development, but requires
# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
# code size when deploying.
console_error_panic_hook = { version = "0.1.6", optional = true }

serde_json = { workspace = true }

cairo-lang-sierra = { workspace = true }
cairo-vm = { workspace = true }
cairo1-run = { path = "../../cairo1-run", default-features = false }
59 changes: 59 additions & 0 deletions examples/wasm-demo-cairo1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Demo of `cairo-vm` on WebAssembly (Cairo 1)

While cairo-vm is compatible with WebAssembly, it doesn't implement any bindings to it.
Instead, create a new WebAssembly crate with cairo-vm and cairo1-run as dependencies and implement the required functionality there.

Since mimalloc is not automatically compilable to WebAssembly, the cairo-vm dependency should disable the default features, which will in turn disable mimalloc. Simliar to this, WebAssembly is
not compatible with rust standard library. For this reason, cairo1-run should also disable the default features.

A working example is provided in this repository.

## Dependencies

To compile and run the example you need:

- a Cairo 1 or Cairo 2 compiler
- the _wasm-pack_ crate
- some HTTP server (for example: the `live-server` npm module)

> **Note**
> The first two dependencies can be installed via the repository's installation script (see ["Installation script"](../../README.md#installation-script))

## Building

To build the example, first you need to compile your Cairo Program, using either cairo 1 or cairo 2 compiler:

If cairo 1 is used:

```sh
cairo-compile -rs ../../cairo_programs/cairo-1-programs/bitwise.cairo ../../cairo_programs/cairo-1-programs/bitwise.sierra
```

If cairo 2 is used:

```sh
cairo-compile -r ../../cairo_programs/cairo-1-programs/bitwise.cairo ../../cairo_programs/cairo-1-programs/bitwise.sierra
```

> WARNING: This example uses `cairo1-run::cairo_run_program` which expectes the program to be compiled with debug names. By default, `cairo-compile` does not include debug names in sierra. Due to this, the flag `-r` or `--replace-ids` is needed.

compile the WebAssembly package:

```sh
wasm-pack build --target=web
```

This will generate a javascript module that is directly loadable by the browser.

## Running

To run the example webpage, you need to run an HTTP server.
For example, using the _live-server_ npm module:

```sh
# while in <repo>/examples/wasm-demo-cairo1
npx live-server
```

> **Warning**
> Trying to run `index.html` directly (i.e. URL starts with `file://`) will result in a CORS error.
12 changes: 12 additions & 0 deletions examples/wasm-demo-cairo1/bitwise.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
fn main() -> u128 {
let a = 1234_u128;
let b = 5678_u128;

let c0 = a & b;
let c1 = a ^ b;
let c2 = a | b;

let c3 = c0 + c1 + c2;

c3
}
30 changes: 30 additions & 0 deletions examples/wasm-demo-cairo1/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Cairo WebAssembly Demo with Cairo 1</title>

<script type="module">
import init, { runCairoProgram } from './pkg/wasm_demo_cairo1.js';

// Initialize WebAssembly module.
// Note: This calls the `start()` function automatically.
await init();

// Run cairo-rs through our proxy function.
const value = await runCairoProgram();

// Display the result.
document.getElementById('result').innerHTML += value;
</script>
</head>

<body>
<p id="result">Result: </p>
</body>

</html>
Loading
Loading