├── .devcontainer ├── Dockerfile └── devcontainer.json ├── .github └── workflows │ └── deno.yml ├── .gitignore ├── .vscode ├── settings.json └── tasks.json ├── Cargo.toml ├── README.md ├── deno ├── server.ts └── test.ts ├── docs └── img │ └── SSVM-rust-deno.gif └── src └── lib.rs /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------------------------------------- 2 | # Copyright (c) Microsoft Corporation. All rights reserved. 3 | # Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. 4 | #------------------------------------------------------------------------------------------------------------- 5 | 6 | FROM rust:1 7 | 8 | # This Dockerfile adds a non-root user with sudo access. Use the "remoteUser" 9 | # property in devcontainer.json to use it. On Linux, the container user's GID/UIDs 10 | # will be updated to match your local UID/GID (when using the dockerFile property). 11 | # See https://aka.ms/vscode-remote/containers/non-root-user for details. 12 | ARG USERNAME=vscode 13 | ARG USER_UID=1000 14 | ARG USER_GID=$USER_UID 15 | 16 | # Avoid warnings by switching to noninteractive 17 | ENV DEBIAN_FRONTEND=noninteractive 18 | 19 | # Configure apt and install packages 20 | RUN apt-get update \ 21 | && apt-get -y install --no-install-recommends apt-utils dialog 2>&1 \ 22 | # 23 | # Verify git, needed tools installed 24 | && apt-get -y install git openssh-client less iproute2 procps lsb-release \ 25 | # 26 | # Install lldb, vadimcn.vscode-lldb VSCode extension dependencies 27 | && apt-get install -y lldb python3-minimal libpython3.7 \ 28 | # 29 | # Install Rust components 30 | && rustup update 2>&1 \ 31 | && rustup component add rls rust-analysis rust-src rustfmt clippy 2>&1 \ 32 | # 33 | # Create a non-root user to use if preferred - see https://aka.ms/vscode-remote/containers/non-root-user. 34 | && groupadd --gid $USER_GID $USERNAME \ 35 | && useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME \ 36 | # [Optional] Add sudo support for the non-root user 37 | && apt-get install -y sudo \ 38 | && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME\ 39 | && chmod 0440 /etc/sudoers.d/$USERNAME \ 40 | # 41 | # Install deno 42 | # 43 | && curl -fsSL https://deno.land/x/install/install.sh | sh \ 44 | # 45 | # Install ssvmup 46 | # 47 | && curl https://raw.githubusercontent.com/second-state/ssvmup/master/installer/init.sh -sSf | sh \ 48 | # 49 | # Clean up 50 | && apt-get autoremove -y \ 51 | && apt-get clean -y \ 52 | && rm -rf /var/lib/apt/lists/* 53 | 54 | # Switch back to dialog for any ad-hoc use of apt-get 55 | ENV PATH="/root/.deno/bin:${PATH}" 56 | ENV DEBIAN_FRONTEND=dialog 57 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Second State Rust Deno", 3 | "dockerFile": "Dockerfile", 4 | 5 | // Set *default* container specific settings.json values on container create. 6 | "settings": { 7 | "terminal.integrated.shell.linux": "/bin/bash", 8 | "lldb.executable": "/usr/bin/lldb" 9 | }, 10 | 11 | // Add the IDs of extensions you want installed when the container is created. 12 | "extensions": [ 13 | "rust-lang.rust", 14 | "bungcip.better-toml", 15 | "denoland.vscode-deno" 16 | ], 17 | 18 | "forwardPorts": [8000] 19 | 20 | // Use 'postCreateCommand' to run commands after the container is created. 21 | // "postCreateCommand": "yarn install", 22 | 23 | // Uncomment to connect as a non-root user. See https://aka.ms/vscode-remote/containers/non-root. 24 | // "remoteUser": "node" 25 | } 26 | -------------------------------------------------------------------------------- /.github/workflows/deno.yml: -------------------------------------------------------------------------------- 1 | name: Build and test 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | workflow_dispatch: 9 | branches: [ master ] 10 | 11 | jobs: 12 | build: 13 | 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v2 18 | 19 | - name: Install deno and ssvmup 20 | run: | 21 | curl -fsSL https://deno.land/x/install/install.sh | sh 22 | curl https://raw.githubusercontent.com/second-state/ssvmup/master/installer/init.sh -sSf | sh 23 | 24 | - name: Build 25 | run: ssvmup build --target deno 26 | 27 | - name: Test 28 | run: | 29 | $HOME/.deno/bin/deno run --allow-read --allow-env --unstable deno/test.ts 30 | ssvmup clean 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | target 4 | 5 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 6 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 7 | Cargo.lock 8 | 9 | # These are backup files generated by rustfmt 10 | **/*.rs.bk 11 | 12 | # nodejs 13 | node_modules 14 | build 15 | npm-debug.log 16 | package-lock.json 17 | 18 | # ssvm 19 | pkg 20 | 21 | # local computer 22 | .env 23 | .DS_Store 24 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "deno.enable": true, 3 | "search.exclude": { 4 | "**/target": true 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [{ 4 | "label": "ssvmup build", 5 | "type": "shell", 6 | "command": "ssvmup build --target deno", 7 | "args": [], 8 | "problemMatcher": [] 9 | }] 10 | } 11 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "functions" 3 | version = "0.1.0" 4 | authors = ["michael@secondstate.io"] 5 | edition = "2018" 6 | 7 | [lib] 8 | name = "functions_lib" 9 | path = "src/lib.rs" 10 | crate-type =["cdylib"] 11 | 12 | [dependencies] 13 | num-integer = "0.1" 14 | sha3 = "0.8.2" 15 | serde = { version = "1.0", features = ["derive"] } 16 | serde_json = "1.0" 17 | wasm-bindgen = "=0.2.61" 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Build and test](https://github.com/second-state/ssvm-deno-starter/workflows/Build%20and%20test/badge.svg) 2 | 3 | Check out this tutorial article: *[Deno Apps with WebAssembly, Rust, and WASI](https://www.secondstate.io/articles/deno-webassembly-rust-wasi/)* 4 | 5 | ## Prerequisites 6 | 7 | [Install Deno](https://deno.land/manual/getting_started/installation) 8 | 9 | [Install Rust](https://www.rust-lang.org/tools/install) 10 | 11 | Also, if you have not done so, please bring your Linux system up to date with dev tools. 12 | 13 | ``` 14 | sudo apt install build-essential curl wget git vim libboost-all-dev 15 | ``` 16 | 17 | ## Setup 18 | 19 | The command below installs the [ssvmup tooling](https://www.secondstate.io/articles/ssvmup/). 20 | 21 | ``` 22 | $ curl https://raw.githubusercontent.com/second-state/ssvmup/master/installer/init.sh -sSf | sh 23 | ``` 24 | 25 | ## Build 26 | 27 | ``` 28 | $ ssvmup build --target deno 29 | ``` 30 | 31 | ## Test 32 | 33 | ``` 34 | $ deno run --allow-read --allow-env --unstable deno/test.ts 35 | ``` 36 | 37 | NOTE: If you encounter an error here, most likely your Deno install and cached library files are out of sync. Use the [deno cache --reload command to fix this issue](https://www.secondstate.io/articles/reload-deno-cache/). 38 | 39 | ## Run 40 | 41 | ``` 42 | $ deno run --allow-read --allow-net --allow-env --unstable deno/server.ts 43 | ``` 44 | 45 | ## User test 46 | 47 | ``` 48 | $ curl http://localhost:8000/ 49 | hello World 50 | ``` 51 | 52 | ## Next steps 53 | 54 | Check out the [SSVM Deno repository for more WebAssembly examples on Deno](https://github.com/second-state/wasm-learning/tree/master/deno). 55 | 56 | Tutorial article: *[Deno Apps with WebAssembly, Rust, and WASI](https://www.secondstate.io/articles/deno-webassembly-rust-wasi/)* 57 | 58 | -------------------------------------------------------------------------------- /deno/server.ts: -------------------------------------------------------------------------------- 1 | import { serve } from "https://deno.land/std/http/server.ts"; 2 | import { say } from '../pkg/functions_lib.js'; 3 | 4 | type Resp = { 5 | body: string; 6 | } 7 | 8 | const s = serve({ port: 8000 }); 9 | console.log("http://localhost:8000/"); 10 | for await (const req of s) { 11 | let r = {} as Resp; 12 | r.body = say (" World\n"); 13 | req.respond(r); 14 | } 15 | -------------------------------------------------------------------------------- /deno/test.ts: -------------------------------------------------------------------------------- 1 | import { say, obfusticate, lowest_common_denominator, sha3_digest, keccak_digest, create_line } from '../pkg/functions_lib.js'; 2 | 3 | const encoder = new TextEncoder(); 4 | 5 | console.log( say("SSVM") ); 6 | console.log( obfusticate("A quick brown fox jumps over the lazy dog") ); 7 | console.log( lowest_common_denominator(123, 2) ); 8 | console.log( sha3_digest(encoder.encode("This is an important message")) ); 9 | console.log( keccak_digest(encoder.encode("This is an important message")) ); 10 | 11 | var p1 = {x:1.5, y:3.8}; 12 | var p2 = {x:2.5, y:5.8}; 13 | var line = JSON.parse(create_line(JSON.stringify(p1), JSON.stringify(p2), "A thin red line")); 14 | console.log( line ); 15 | -------------------------------------------------------------------------------- /docs/img/SSVM-rust-deno.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/second-state/ssvm-deno-starter/ac68ba6111f3fcdea4db5883d2cc19ceb9abd001/docs/img/SSVM-rust-deno.gif -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | use wasm_bindgen::prelude::*; 2 | use num_integer::lcm; 3 | use sha3::{Digest, Sha3_256, Keccak256}; 4 | use serde::{Serialize, Deserialize}; 5 | 6 | #[derive(Serialize, Deserialize, Debug)] 7 | struct Point { 8 | x: f32, 9 | y: f32 10 | } 11 | 12 | #[derive(Serialize, Deserialize, Debug)] 13 | struct Line { 14 | points: Vec, 15 | valid: bool, 16 | length: f32, 17 | desc: String 18 | } 19 | 20 | #[wasm_bindgen] 21 | pub fn create_line (p1: &str, p2: &str, desc: &str) -> String { 22 | let point1: Point = serde_json::from_str(p1).unwrap(); 23 | let point2: Point = serde_json::from_str(p2).unwrap(); 24 | let length = ((point1.x - point2.x) * (point1.x - point2.x) + (point1.y - point2.y) * (point1.y - point2.y)).sqrt(); 25 | 26 | let valid = if length == 0.0 { false } else { true }; 27 | 28 | let line = Line { points: vec![point1, point2], valid: valid, length: length, desc: desc.to_string() }; 29 | 30 | return serde_json::to_string(&line).unwrap(); 31 | } 32 | 33 | #[wasm_bindgen] 34 | pub fn say(s: &str) -> String { 35 | let r = String::from("hello "); 36 | return r + s; 37 | } 38 | 39 | #[wasm_bindgen] 40 | pub fn obfusticate(s: String) -> String { 41 | (&s).chars().map(|c| { 42 | match c { 43 | 'A' ..= 'M' | 'a' ..= 'm' => ((c as u8) + 13) as char, 44 | 'N' ..= 'Z' | 'n' ..= 'z' => ((c as u8) - 13) as char, 45 | _ => c 46 | } 47 | }).collect() 48 | } 49 | 50 | #[wasm_bindgen] 51 | pub fn lowest_common_denominator(a: i32, b: i32) -> i32 { 52 | let r = lcm(a, b); 53 | return r; 54 | } 55 | 56 | #[wasm_bindgen] 57 | pub fn sha3_digest(v: Vec) -> Vec { 58 | return Sha3_256::digest(&v).as_slice().to_vec(); 59 | } 60 | 61 | #[wasm_bindgen] 62 | pub fn keccak_digest(s: &[u8]) -> Vec { 63 | return Keccak256::digest(s).as_slice().to_vec(); 64 | } 65 | --------------------------------------------------------------------------------