forked from dfinity/examples
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: template for motoko/rust examples: project hello (dfinity#134)
This PR tries to create a single, coherent example of the same dapp in both Rust in Motoko. The example is just the default project created with `dfx new (--type rust)` and has both a Motoko (Rust) backend and frontend. (Unfortunately, none of the existing dual language examples are either equivalent or simple enough.) Each project has: - [x] A tutorial style README for setting up, building and running the sample - [x] A link to the same example in the other language (if possible). - [x] Makefile (to be used for testing by CI) - [x] GH actions so it can be tested against newer versions of dfx (leveraging the Makefile) - [x] Docs onepager, c.f. dfinity/docs#659 - [x] RECIPE.md outlining steps required for adding a new dual language example. Issues: - How does one test the asset canister/frontend? The only existing example is out of date and commented out. - Might be nicer if we could have the adoc in this examples repo, not the docs repo.
- Loading branch information
Showing
35 changed files
with
17,898 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
name: hello-example | ||
on: | ||
push: | ||
branches: | ||
- master | ||
pull_request: | ||
jobs: | ||
motoko-hello-example-darwin: | ||
runs-on: macos-10.15 | ||
steps: | ||
- uses: actions/checkout@v1 | ||
- name: Provision Darwin | ||
run: bash .github/workflows/provision-darwin.sh | ||
- name: Motoko Hello Example Darwin | ||
run: | | ||
dfx start --background | ||
pushd motoko/hello | ||
make test | ||
popd | ||
motoko-hello-example-linux: | ||
runs-on: ubuntu-20.04 | ||
steps: | ||
- uses: actions/checkout@v1 | ||
- name: Provision Linux | ||
run: bash .github/workflows/provision-linux.sh | ||
- name: Motoko Hello Example Linux | ||
run: | | ||
dfx start --background | ||
pushd motoko/hello | ||
make test | ||
popd | ||
rust-hello-example-darwin: | ||
runs-on: macos-10.15 | ||
steps: | ||
- uses: actions/checkout@v1 | ||
- name: Provision Darwin | ||
run: bash .github/workflows/provision-darwin.sh | ||
- name: Install Rust Darwin | ||
run: bash .github/workflows/install-rust-darwin.sh | ||
- name: Rust Hello Example Darwin | ||
run: | | ||
dfx start --background | ||
pushd rust/hello | ||
make test | ||
popd | ||
rust-hello-example-linux: | ||
runs-on: ubuntu-20.04 | ||
steps: | ||
- uses: actions/checkout@v1 | ||
- name: Provision Linux | ||
run: bash .github/workflows/provision-linux.sh | ||
- name: Install Rust Linux | ||
run: bash .github/workflows/install-rust-linux.sh | ||
- name: Rust Hello Example Linux | ||
run: | | ||
dfx start --background | ||
pushd rust/hello | ||
make test | ||
popd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#!/bin/bash | ||
|
||
set -ex | ||
|
||
# Enter temporary directory. | ||
pushd /tmp | ||
|
||
# Install cmake | ||
brew install cmake | ||
|
||
# Install rust | ||
curl --location --output install-rustup.sh "https://sh.rustup.rs" | ||
bash install-rustup.sh -y | ||
rustup target add wasm32-unknown-unknown | ||
|
||
# Exit temporary directory. | ||
popd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#!/bin/bash | ||
|
||
set -ex | ||
|
||
# Enter temporary directory. | ||
pushd /tmp | ||
|
||
# Install cmake | ||
sudo apt-get install --yes cmake | ||
|
||
# Install rust | ||
wget --output-document install-rustup.sh "https://sh.rustup.rs" | ||
sudo bash install-rustup.sh -y | ||
rustup target add wasm32-unknown-unknown | ||
|
||
# Set environment variables. | ||
echo "$HOME/.cargo/bin" >> $GITHUB_PATH | ||
|
||
# Exit temporary directory. | ||
popd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# How to Add a New Example | ||
|
||
Ideally, each example should come with both Rust and Motoko implementations, | ||
implementing the same Candid interface (and, ideally, semantics). | ||
|
||
To illustrate the pattern, this repo now contains one such example, project `hello`. | ||
|
||
The (dual) sources for the projects live in: | ||
|
||
motoko/hello | ||
rust/hello | ||
|
||
When adding a new dfx generated project, make sure to delete its GH metadata files (.gitignore, .git etc). | ||
|
||
Each project should have a similar, but language specific `README.md`. E.g. | ||
|
||
motoko/hello/README.md | ||
rust/hello/README.md | ||
|
||
Each `README.md` should link to the other project's README.md for | ||
language-curious readers. | ||
|
||
# CI | ||
|
||
Apart from the standard dfx material, each project should provide a | ||
`Makefile` used by GitHub Actions CI to run (very) basic tests. E.g. | ||
|
||
motoko/hello/Makefile | ||
rust/hello/Makefile | ||
|
||
For each example, there is a single CI file with four build actions to | ||
produce darwin and linux builds and tests of the motoko/rust | ||
projects. E.g. | ||
|
||
.github/workflows/hello.yml | ||
|
||
Implementing the GH action will ensure it runs in CI and gives us some | ||
hope of keeping examples in sync with releases of dfx. | ||
|
||
# Documentation | ||
|
||
In repo dfinity/docs, add some general, language agnostic documentation for the | ||
example. E.g. for `hello`: | ||
|
||
* modules/examples/pages/index.adoc: add new bullet in early subsection pointing pointing to hello.adoc. | ||
* modules/examples/pages/hello.adoc: add one page description of hello example. | ||
* modules/examples/pages/assets/hello.png: screenshot of UI linked by hello.adoc (optional). | ||
* modules/ROOT/nav.adoc: add direct site navigation to hello.adoc. | ||
|
||
# Issues | ||
|
||
This structuring of examples isn't ideal since it requires duplication | ||
of similar files (typically frontend code) but has the advantage that | ||
Motoko users only need to see Motoko specific content and dually for | ||
Rust. | ||
|
||
It also makes it possible to have language restricted examples, for | ||
example, when the other language does not support a particular example | ||
well. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
t.PHONY: all | ||
all: build | ||
|
||
.PHONY: node_modules | ||
.SILENT: node_modules | ||
node_modules: | ||
npm install | ||
|
||
.PHONY: build | ||
.SILENT: build | ||
build: node_modules | ||
dfx canister create --all | ||
dfx build | ||
|
||
.PHONY: install | ||
.SILENT: install | ||
install: build | ||
dfx canister install --all | ||
|
||
.PHONY: upgrade | ||
.SILENT: upgrade | ||
upgrade: build | ||
dfx canister install --all --mode=upgrade | ||
|
||
.PHONY: test | ||
.SILENT: test | ||
test: install | ||
dfx canister call hello greet '("everyone")' \ | ||
| grep '("Hello, everyone!")' && echo 'PASS' | ||
|
||
.PHONY: clean | ||
.SILENT: clean | ||
clean: | ||
rm -fr .dfx |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
# Hello Example | ||
|
||
## Summary | ||
|
||
This example demonstrates a dead simple dapp consisting of two canister smart contracts: | ||
|
||
* a simple backend canister, `hello`, implementing the logic of the application in Motoko, and | ||
* a simple frontend asset canister, `hello_assets` serving the assets of the dapp's web user interface. | ||
|
||
This example is based on the default project created by running `dfx new hello` as described | ||
[here](https://smartcontracts.org/docs/quickstart/local-quickstart.html). | ||
|
||
### Rust variant | ||
|
||
A version of this example with a Rust implementation of canister `hello` can be found [here](../../rust/hello/README.md). | ||
|
||
## Interface | ||
|
||
Canister `hello` is defined as a Motoko actor: | ||
|
||
* [src/hello/main.mo](src/hello/main.mo) | ||
|
||
with the Candid interface: | ||
|
||
``` | ||
service : { | ||
greet: (text) -> (text); | ||
} | ||
``` | ||
|
||
The frontend displays a page with an HTML text box for the argument and a button for calling the function greet with that argument. The result of the call is displayed in a message box. | ||
|
||
The relevant frontend code is: | ||
|
||
* [src/hello_assets/src/index.html](src/hello_assets/src/index.html) | ||
* [src/hello_assets/src/index.jsx](src/hello_assets/src/index.jsx) | ||
|
||
|
||
## Requirements | ||
|
||
The example requires an installation of: | ||
|
||
* [DFINITY Canister SDK](https://sdk.dfinity.org). | ||
* `node.js` (to build the web frontend). | ||
|
||
(The Rust version of this example additionally requires a working Rust environment.) | ||
|
||
## Setup | ||
|
||
Check, you have stopped any local canister execution environment (i.e. `replica`) or other network process that would create a port conflict on 8000. | ||
|
||
|
||
## Running Locally | ||
|
||
Using two terminal windows, do the following steps: | ||
|
||
1. Open the first terminal window. | ||
|
||
1. Start a local canister execution environment | ||
|
||
```text | ||
dfx start | ||
``` | ||
|
||
This command produces a lot of distracting diagnostic output which is best ignored by continuing in a second terminal. | ||
|
||
1. Open the second terminal window. | ||
|
||
1. Ensure that the required `node` modules are available in your project directory, if needed, by running the following command: | ||
|
||
```text | ||
npm install | ||
``` | ||
|
||
1. Register, build and deploy the project. | ||
|
||
```text | ||
dfx deploy | ||
``` | ||
|
||
1. Call the hello canister's greet function: | ||
|
||
```text | ||
dfx canister call hello greet '("everyone")' | ||
``` | ||
|
||
1. Observe the following result. | ||
|
||
```text | ||
("Hello,a everyone!") | ||
``` | ||
|
||
The previous steps use `dfx` to directly call the function on the `hello` (backend) canister. | ||
|
||
To access the web user interface of the dapp, that is served by canister `hello_assets`, do the following: | ||
|
||
1. Determine the URL of the `hello_assets` asset canister. | ||
|
||
```text | ||
echo "http://localhost:8000/?canisterId=$(dfx canister id hello_assets)" | ||
``` | ||
|
||
1. Navigate to the URL in your browser. | ||
|
||
2. The browser should display a simple HTML page with a sample asset image file, an input field, and a button. | ||
|
||
3. Enter the text `everyone` and click the button to see the greeting returned by the backend `hello` canister. | ||
|
||
## Troubleshooting | ||
|
||
If the web page doesn't display properly, or displays the wrong contents, | ||
you may need to clear your browser cache. | ||
|
||
Alternatively, open the URL in a fresh, in-private browser window to start with a clean cache. | ||
|
||
## Links | ||
|
||
For instructions on how to create this example from scratch as well as a more detailed walkthrough and some tips on frontend development using a development server, see: | ||
|
||
- [Local Development](https://smartcontracts.org/docs/quickstart/local-quickstart.html) | ||
|
||
Other related links you might find useful are: | ||
|
||
- [Motoko Programming Language Guide](https://sdk.dfinity.org/docs/language-guide/motoko.html) | ||
- [Motoko Language Quick Reference](https://sdk.dfinity.org/docs/language-guide/language-manual.html) | ||
- [Candid Introduction](https://smartcontracts.org/docs/candid-guide/candid-intro.html) | ||
- [JavaScript API Reference](https://erxue-5aaaa-aaaab-qaagq-cai.raw.ic0.app) | ||
- [Troubleshoot issues](https://smartcontracts.org/docs/developers-guide/troubleshooting.html) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
{ | ||
"canisters": { | ||
"hello": { | ||
"main": "src/hello/main.mo", | ||
"type": "motoko" | ||
}, | ||
"hello_assets": { | ||
"dependencies": [ | ||
"hello" | ||
], | ||
"frontend": { | ||
"entrypoint": "src/hello_assets/src/index.html" | ||
}, | ||
"source": [ | ||
"src/hello_assets/assets", | ||
"dist/hello_assets/" | ||
], | ||
"type": "assets" | ||
} | ||
}, | ||
"defaults": { | ||
"build": { | ||
"args": "", | ||
"packtool": "" | ||
} | ||
}, | ||
"dfx": "0.8.5", | ||
"networks": { | ||
"local": { | ||
"bind": "127.0.0.1:8000", | ||
"type": "ephemeral" | ||
} | ||
}, | ||
"version": 1 | ||
} |
Oops, something went wrong.