Skip to content
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

Wasm cairo integration #101

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
58 changes: 58 additions & 0 deletions assets/js/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import * as params from '@params';

const maxWorkers = 1
const worker = new Worker(params.worker);

window.runButtonAction = async (innerHTML) =>{
const code = extractCodes(innerHTML);
//if code include #[starknet::contract]
if (code.includes("#[starknet::contract]")) {
return compileStarknetContract(code);
}
return runCairoProgram(code);
};

const runCairoProgram = async (cairo_program) => {
return new Promise((resolve, reject) => {
worker.postMessage({
data: cairo_program,
availableGas: undefined,
printFullMemory: false,
useDBGPrintHint: true,
functionToRun: "runCairoProgram"
});

worker.onmessage = function(e) {
resolve(e.data);
};

worker.onerror = function(error) {
reject(error);
};
});
}

const compileStarknetContract = async (cairo_program) => {
return new Promise((resolve, reject) => {
worker.postMessage({
data: cairo_program,
functionToRun: "compileStarknetContract"
});

worker.onmessage = function(e) {
resolve(e.data);
};

worker.onerror = function(error) {
reject(error);
};
});
}

const extractCodes = (htmlString) => {
const parser = new DOMParser();
const doc = parser.parseFromString(htmlString, 'text/html');
const codeElement = doc.querySelector('code');
return codeElement.textContent;
}

28 changes: 28 additions & 0 deletions assets/js/worker.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import init, {greet, runCairoProgram, compileStarknetContract} from 'module/wasm-cairo';
import * as params from '@params';

(async () => {
await init(params.wasm_file);
console.log(greet("Cairo-by-Example"));
})();


onmessage = function (e) {
const { data, functionToRun } = e.data;
init(params.wasm_file).then(() => {
let result;
switch (functionToRun) {
case "runCairoProgram":
const { availableGas, printFullMemory, useDBGPrintHint } = e.data;
result = runCairoProgram(data, availableGas, printFullMemory, useDBGPrintHint);
break;
case "compileStarknetContract":
result = compileStarknetContract(data, false)
break;
default:
console.error(`Unexpected function: ${functionToRun}`);
return;
}
postMessage(result);
});
}
89 changes: 89 additions & 0 deletions assets/module/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<div align="center">

<h1><code>WASM-Cairo</code></h1>

<strong>A suite of development tools and an environment for Cairo, all based on WebAssembly.</strong>

[Github](https://github.com/cryptonerdcn/wasm-cairo)

<sub>Built with 🦀🕸 by <a href="https://twitter.com/cryptonerdcn">cryptonerdcn from Starknet Astro</a></sub>
</div>


## 🚴 Usage


### 🛠️ Build WASM-bindgen's WASM-Cairo Toolkit
With Modules

```
wasm-pack build --release --target --out-dir ./pkg
```

No Modules

```
wasm-pack build --release --target no-modules --out-dir ./pkg
```

You will find `wasm-cairo_bg.wasm` and `wasm-cairo.js` in `pkg` folder.


### 🛠️ Build Astro Editor

```
wasm-pack build --release --target no-modules --out-dir ./dist/pkg --out-name wasm-cairo
```

Then run
```
node app.js
```
For local web instance.

### 🛠️ Build WASMTIME's WASM-Cairo Toolkit

```
cargo build --target wasm32-wasi --release
```

You can test it by using:

Compile Cairo

```
./wasmtime_test.sh compileCairoProgram ./cairo_files/HelloStarknetAstro.cairo ./cairo_files/HelloStarknetAstro.sierra
```

Run
```
./wasmtime_test.sh runCairoProgram ./cairo_files/HelloStarknetAstro.cairo
```

Compile Contract

```
./wasmtime_test.sh compileStarknetContract ./cairo_files/erc20.cairo ./cairo_files/erc20.json
```

## 🔋 Batteries Included

* [`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) for communicating
between WebAssembly and JavaScript.
* [`console_error_panic_hook`](https://github.com/rustwasm/console_error_panic_hook)
for logging panic messages to the developer console.
* [`wee_alloc`](https://github.com/rustwasm/wee_alloc), an allocator optimized
for small code size.
* [`Cairo`](https://github.com/starkware-libs/cairo) for Cairo-lang support.
* `LICENSE-APACHE` and `LICENSE-MIT`: most Rust projects are licensed this way, so these are included for you

## License

* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)

### Contribution

Unless you explicitly state otherwise, any contribution intentionally
submitted for inclusion in the work by you, as defined in the Apache-2.0
license, shall be dual licensed as above, without any additional terms or
conditions.
17 changes: 17 additions & 0 deletions assets/module/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "wasm-cairo",
"collaborators": [
"cryptonerdcn <[email protected]>"
],
"version": "0.2.1",
"files": [
"wasm-cairo_bg.wasm",
"wasm-cairo.js",
"wasm-cairo.d.ts"
],
"module": "wasm-cairo.js",
"types": "wasm-cairo.d.ts",
"sideEffects": [
"./snippets/*"
]
}
62 changes: 62 additions & 0 deletions assets/module/wasm-cairo.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/* tslint:disable */
/* eslint-disable */
/**
* @param {string} s
* @returns {string}
*/
export function greet(s: string): string;
/**
* @param {string} cairo_program
* @param {boolean} replace_ids
* @returns {string}
*/
export function compileCairoProgram(cairo_program: string, replace_ids: boolean): string;
/**
* @param {string} cairo_program
* @param {number | undefined} available_gas
* @param {boolean} print_full_memory
* @param {boolean} use_dbg_print_hint
* @returns {string}
*/
export function runCairoProgram(cairo_program: string, available_gas: number | undefined, print_full_memory: boolean, use_dbg_print_hint: boolean): string;
/**
* @param {string} starknet_contract
* @param {boolean} replace_ids
* @returns {string}
*/
export function compileStarknetContract(starknet_contract: string, replace_ids: boolean): string;

export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;

export interface InitOutput {
readonly memory: WebAssembly.Memory;
readonly greet: (a: number, b: number, c: number) => void;
readonly compileCairoProgram: (a: number, b: number, c: number, d: number) => void;
readonly runCairoProgram: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
readonly compileStarknetContract: (a: number, b: number, c: number, d: number) => void;
readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
readonly __wbindgen_malloc: (a: number, b: number) => number;
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
readonly __wbindgen_free: (a: number, b: number, c: number) => void;
}

export type SyncInitInput = BufferSource | WebAssembly.Module;
/**
* Instantiates the given `module`, which can either be bytes or
* a precompiled `WebAssembly.Module`.
*
* @param {SyncInitInput} module
*
* @returns {InitOutput}
*/
export function initSync(module: SyncInitInput): InitOutput;

/**
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
* for everything else, calls `WebAssembly.instantiate` directly.
*
* @param {InitInput | Promise<InitInput>} module_or_path
*
* @returns {Promise<InitOutput>}
*/
export default function __wbg_init (module_or_path?: InitInput | Promise<InitInput>): Promise<InitOutput>;
Loading