From bba91bf377224381b5f2ed09c33e9e966966f7b8 Mon Sep 17 00:00:00 2001 From: "Paul H. Liu" Date: Wed, 11 Dec 2024 03:34:33 -0800 Subject: [PATCH 01/51] fix: drop Host header in https outcall request --- motoko/send_http_get/src/send_http_get_backend/main.mo | 1 - motoko/send_http_post/src/send_http_post_backend/main.mo | 1 - rust/send_http_get/src/send_http_get_backend/src/lib.rs | 6 +----- rust/send_http_post/src/send_http_post_backend/src/lib.rs | 6 +----- 4 files changed, 2 insertions(+), 12 deletions(-) diff --git a/motoko/send_http_get/src/send_http_get_backend/main.mo b/motoko/send_http_get/src/send_http_get_backend/main.mo index b8851fc0b..475c45be6 100644 --- a/motoko/send_http_get/src/send_http_get_backend/main.mo +++ b/motoko/send_http_get/src/send_http_get_backend/main.mo @@ -69,7 +69,6 @@ actor { // 2.2 prepare headers for the system http_request call let request_headers = [ - { name = "Host"; value = host # ":443" }, { name = "User-Agent"; value = "exchange_rate_canister" }, ]; diff --git a/motoko/send_http_post/src/send_http_post_backend/main.mo b/motoko/send_http_post/src/send_http_post_backend/main.mo index 1e441394e..1e432cc5b 100644 --- a/motoko/send_http_post/src/send_http_post_backend/main.mo +++ b/motoko/send_http_post/src/send_http_post_backend/main.mo @@ -64,7 +64,6 @@ actor { //idempotency keys should be unique so we create a function that generates them. let idempotency_key: Text = generateUUID(); let request_headers = [ - { name = "Host"; value = host # ":443" }, { name = "User-Agent"; value = "http_post_sample" }, { name= "Content-Type"; value = "application/json" }, { name= "Idempotency-Key"; value = idempotency_key } diff --git a/rust/send_http_get/src/send_http_get_backend/src/lib.rs b/rust/send_http_get/src/send_http_get_backend/src/lib.rs index a8aba5c09..382e18411 100644 --- a/rust/send_http_get/src/send_http_get_backend/src/lib.rs +++ b/rust/send_http_get/src/send_http_get_backend/src/lib.rs @@ -37,10 +37,6 @@ async fn get_icp_usd_exchange() -> String { // 2.2 prepare headers for the system http_request call //Note that `HttpHeader` is declared in line 4 let request_headers = vec![ - HttpHeader { - name: "Host".to_string(), - value: format!("{host}:443"), - }, HttpHeader { name: "User-Agent".to_string(), value: "exchange_rate_canister".to_string(), @@ -168,4 +164,4 @@ fn transform(raw: TransformArgs) -> HttpResponse { ic_cdk::api::print(format!("Received an error from coinbase: err = {:?}", raw)); } res -} \ No newline at end of file +} diff --git a/rust/send_http_post/src/send_http_post_backend/src/lib.rs b/rust/send_http_post/src/send_http_post_backend/src/lib.rs index 246c31d99..0f6845491 100644 --- a/rust/send_http_post/src/send_http_post_backend/src/lib.rs +++ b/rust/send_http_post/src/send_http_post_backend/src/lib.rs @@ -28,10 +28,6 @@ async fn send_http_post_request() -> String { // 2.2 prepare headers for the system http_request call //Note that `HttpHeader` is declared in line 4 let request_headers = vec![ - HttpHeader { - name: "Host".to_string(), - value: format!("{host}:443"), - }, HttpHeader { name: "User-Agent".to_string(), value: "demo_HTTP_POST_canister".to_string(), @@ -191,4 +187,4 @@ fn transform(raw: TransformArgs) -> HttpResponse { ic_cdk::api::print(format!("Received an error from coinbase: err = {:?}", raw)); } res -} \ No newline at end of file +} From e876b1ad461d44ceafc29f27c9f2de12e67cf12d Mon Sep 17 00:00:00 2001 From: Jessie Mongeon Date: Wed, 18 Dec 2024 16:02:09 -0600 Subject: [PATCH 02/51] Update Motoko project READMEs --- archive/motoko/persistent-storage/README.md | 3 +- motoko/basic_bitcoin/README.md | 26 ++--- motoko/basic_dao/README.md | 27 ++--- motoko/canister_logs/README.md | 64 +++++------ motoko/cert-var/README.md | 36 +++--- motoko/classes/README.md | 25 ++-- motoko/composite_query/README.md | 39 +++---- motoko/counter/README.md | 23 ++-- motoko/encrypted-notes-dapp-vetkd/README.md | 64 +++++------ motoko/encrypted-notes-dapp/README.md | 47 ++++---- motoko/hello_cycles/README.md | 33 +++--- motoko/ic-pos/README.md | 50 ++++---- motoko/icrc2-swap/README.md | 56 ++++----- .../internet_identity_integration/README.md | 47 ++++---- motoko/life/README.md | 22 ++-- motoko/minimal-counter-dapp/README.md | 27 ++--- motoko/parallel_calls/README.md | 30 ++--- motoko/pub-sub/README.md | 22 ++-- motoko/random_maze/README.md | 20 ++-- motoko/send_http_get/README.md | 18 --- motoko/send_http_post/README.md | 18 --- motoko/superheroes/README.md | 26 ++--- motoko/threshold-ecdsa/README.md | 55 ++++----- motoko/threshold-schnorr/README.md | 40 +++---- motoko/token_transfer/README.md | 88 +++++--------- motoko/token_transfer_from/README.md | 108 ++++++++---------- motoko/vetkd/README.md | 41 +++---- motoko/whoami/README.md | 25 ++-- 28 files changed, 429 insertions(+), 651 deletions(-) diff --git a/archive/motoko/persistent-storage/README.md b/archive/motoko/persistent-storage/README.md index a56e2b4ee..5ba84e19f 100644 --- a/archive/motoko/persistent-storage/README.md +++ b/archive/motoko/persistent-storage/README.md @@ -33,7 +33,8 @@ This example requires an installation of: Begin by opening a terminal window. -### Step 1: Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the command: +### Step 1: Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: + ```bash cd examples/motoko/persistent-storage diff --git a/motoko/basic_bitcoin/README.md b/motoko/basic_bitcoin/README.md index f1857f9d9..5896c1da6 100644 --- a/motoko/basic_bitcoin/README.md +++ b/motoko/basic_bitcoin/README.md @@ -1,12 +1,5 @@ ---- -keywords: [advanced, motoko, bitcoin, bitcoin integration, btc] ---- - # Basic Bitcoin -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/basic_bitcoin) - -## Overview This tutorial will walk you through how to deploy a sample [canister smart contract](https://wiki.internetcomputer.org/wiki/Canister_smart_contract) **that can send and receive Bitcoin** on the Internet Computer. ## Architecture @@ -21,22 +14,23 @@ For a deeper understanding of the ICP < > BTC integration, see the [Bitcoin inte ## Prerequisites -* [x] Install the [IC - SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). For local testing, `dfx >= 0.22.0` is required. +- [x] Install the [IC + SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` + +> [!WARNING] +> This example is designed to be deployed on the mainnet. It will return errors when deployed locally; these errors are expected. -:::info -This example is designed to be deployed on the mainnet. It will return errors when deployed locally; these errors are expected. -::: +Begin by opening a terminal window. -## Step 1: Building and deploying sample code +## Step 1: Setup the project environment -### Clone the smart contract +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: -To clone and build the smart contract in **Motoko**: ```bash -git clone https://github.com/dfinity/examples cd examples/motoko/basic_bitcoin +dfx start --background ``` ### Install MOPS diff --git a/motoko/basic_dao/README.md b/motoko/basic_dao/README.md index 0941966f2..01cc7ad80 100644 --- a/motoko/basic_dao/README.md +++ b/motoko/basic_dao/README.md @@ -1,15 +1,7 @@ ---- -keywords: [advanced, motoko, dao, decentralized organization, decentralized org] ---- - # Basic DAO -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/basic_dao) - This sample project demonstrates a basic [decentralized autonomous organization](https://en.wikipedia.org/wiki/Decentralized_autonomous_organization) (DAO) that can be deployed to the [Internet Computer](https://github.com/dfinity/ic). The basic DAO sample code is available in [Motoko](https://github.com/dfinity/examples/tree/master/motoko/basic_dao) and [Rust](https://github.com/dfinity/examples/tree/master/rust/basic_dao). You can see a quick introduction on [YouTube](https://youtu.be/3IcYlieA-EE). -## Overview - A `basic_dao` can be initialized with a set of accounts: mappings from principal IDs to a number of tokens. Account owners can query their account balance by calling `account_balance` and transfer tokens to other accounts by calling `transfer`. Anyone can call `list_accounts` to view all accounts. Account owners can submit proposals by calling `submit_proposal`. A proposal specifies a canister, method, and arguments for this method. Account owners can cast votes (either `Yes` or `No`) on a proposal by calling `vote`. The amount of votes cast is equal to the amount of tokens the account owner has. If enough `Yes` votes are cast, `basic_dao` will execute the proposal by calling the proposal’s given method with the given args against the given canister. If enough `No` votes are cast, the proposal is not executed, and is instead marked as `Rejected`. @@ -19,30 +11,35 @@ This workflow is demonstrated below. View the [canister service definition](https://github.com/dfinity/examples/blob/master/rust/basic_dao/src/basic_dao/src/basic_dao.did) for more details. -### Prerequisites -This example requires an installation of: +## Prerequisites -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/). +- [x] Install the [IC + SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. - [x] To run the test scripts, you need to download [ic-repl](https://github.com/chenyan2002/ic-repl/releases). - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` Begin by opening a terminal window. - ### Step 1: Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the command: +## Step 1: Setup the project environment + +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: + ```bash cd examples/motoko/basic_dao dfx start --background ``` - ### Step 2: Create test identities with the commands: +## Step 2: Create identities + +Create test identities with the commands: ```bash dfx identity new Alice --disable-encryption; dfx identity use Alice; export ALICE=$(dfx identity get-principal); dfx identity new Bob --disable-encryption; dfx identity use Bob; export BOB=$(dfx identity get-principal); ``` - ### Step 3: Deploy `basic_dao` with initial test accounts. +## Step 3: Deploy `basic_dao` with initial test accounts ```bash dfx deploy --argument "(record { @@ -57,7 +54,7 @@ dfx deploy --argument "(record { })" ``` - ### Step 4: Run the ic-repl test scripts: +## Step 4: Run the `ic-repl` test scripts: ```bash ic-repl tests/account.test.sh diff --git a/motoko/canister_logs/README.md b/motoko/canister_logs/README.md index ad69e31b5..32e3da531 100644 --- a/motoko/canister_logs/README.md +++ b/motoko/canister_logs/README.md @@ -1,66 +1,64 @@ ---- -keywords: [beginner, motoko, canister logs, logging] ---- - # Canister logs -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/canister_logs) - ## Prerequisites -This example requires an installation of: -- [x] DFX version 0.19.0 or newer -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/). -- [x] Download the following project files from GitHub: `git clone https://github.com/dfinity/examples/` +- [x] Install the [IC + SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -You will need to have 3 terminal windows: -- Terminal A: Running a DFX instance and separating its output from anything else -- Terminal B: Deploying a canister and seeing its output -- Terminal C: Reading logs interactively +## Step 1: Setup project environment + +Navigate into the folder containing the project's files and start a local instance of the replica with the command: -### Step 1: Navigate into the folder containing the project's files and start a local instance of the replica with the command: +```shell +dfx start --clean +``` + +You will need to have 3 terminal windows: +- Terminal A: Running a `dfx` instance and separating its output from anything else. +- Terminal B: Deploying a canister and seeing its output. +- Terminal C: Reading logs interactively. ```shell # Terminal A -- for running DFX and separating its output from anything else. -$ cd examples/motoko/canister_logs -$ dfx start --clean +cd examples/motoko/canister_logs # Terminal B -- for deploying the canister and calling its methods. -$ cd examples/motoko/canister_logs +cd examples/motoko/canister_logs # Terminal C -- for polling logs. -$ cd examples/motoko/canister_logs +cd examples/motoko/canister_logs ``` -### Step 2: Deploy the canister: +## Step 2: Deploy the canister ```shell # Terminal B -$ dfx deploy +dfx deploy ``` -### Step 3: Check canister logs: +## Step 3: Check canister logs Expect to see logs from timer traps. ```shell # Terminal B -$ dfx canister logs CanisterLogs +dfx canister logs CanisterLogs [0. 2024-05-23T08:32:26.203980235Z]: right before timer trap [1. 2024-05-23T08:32:26.203980235Z]: [TRAP]: timer trap [2. 2024-05-23T08:32:31.836721763Z]: right before timer trap [3. 2024-05-23T08:32:31.836721763Z]: [TRAP]: timer trap ``` -### Step 4: Call `print` method and check the logs: +## Step 4: Call `print` method and check the logs ```shell # Terminal B -$ dfx canister call CanisterLogs print hi +dfx canister call CanisterLogs print hi () # Expect to see new log entry. -$ dfx canister logs CanisterLogs +dfx canister logs CanisterLogs ... [8. 2024-05-23T08:32:46.598972616Z]: right before timer trap [9. 2024-05-23T08:32:46.598972616Z]: [TRAP]: timer trap @@ -70,7 +68,7 @@ $ dfx canister logs CanisterLogs ... ``` -### Step 5: Start constantly polling logs: +## Step 5: Start constantly polling logs In order not to call `dfx canister logs CanisterLogs` after every canister call in a separate terminal window/pane C start a script that will constantly poll logs: @@ -86,25 +84,25 @@ $ ./poll_logs.sh ... ``` -### Step 6: Call `print`, `trap` and other canister methods: +## Step 6: Call `print`, `trap` and other canister methods ```shell # Terminal B -$ dfx canister call CanisterLogs print hi! +dfx canister call CanisterLogs print hi! () -$ dfx canister call CanisterLogs print hello! +dfx canister call CanisterLogs print hello! () -$ dfx canister call CanisterLogs print yey! +dfx canister call CanisterLogs print yey! () -$ dfx canister call CanisterLogs trap oops! +dfx canister call CanisterLogs trap oops! Error: Failed update call. Caused by: Failed update call. The replica returned a rejection error: reject code CanisterError, reject message Canister bkyz2-fmaaa-aaaaa-qaaaq-cai trapped explicitly: oops!, error code None -$ dfx canister call CanisterLogs memory_oob +dfx canister call CanisterLogs memory_oob Error: Failed update call. Caused by: Failed update call. The replica returned a rejection error: reject code CanisterError, reject message Canister bkyz2-fmaaa-aaaaa-qaaaq-cai trapped explicitly: StableMemory range out of bounds, error code None diff --git a/motoko/cert-var/README.md b/motoko/cert-var/README.md index a0db5f6a8..b0d985766 100644 --- a/motoko/cert-var/README.md +++ b/motoko/cert-var/README.md @@ -1,12 +1,5 @@ ---- -keywords: [intermediate, motoko, cert var, certified variables] ---- - # Certified variables -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/cert-var) - -## Overview This example demonstrates the use of a single cryptographically certified variable, as supported by the Internet Computer. In a nutshell, this example code demonstrates "response certification" for a canister that holds a single 32-bit variable. It has two sides: @@ -49,32 +42,39 @@ This is a Motoko example that does not currently have a Rust variant. ## Prerequisites This example requires an installation of: -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). -- [x] Download [npm](https://nodejs.org/en/download/). +## Prerequisites + +- [x] Install the [IC + SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` Begin by opening a terminal window. -### Step 1: Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the command: +## Step 1: Setup the project environment + +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: + ```bash cd examples/motoko/cert-var dfx start --background ``` -### Step 2: Install the front-end dependencies: +## Step 2: Install the front-end dependencies ```bash npm install ``` -### Step 3: Deploy the canister: +## Step 3: Deploy the canister ```bash dfx deploy ``` -### Step 4: Next, open the `webpack.config.js` file and replace the contents with the following: +## Step 4: Next, open the `webpack.config.js` file. + +Replace the contents with the following: ```javascript const path = require("path"); @@ -188,7 +188,9 @@ module.exports = { }; ``` -### Step 5: Create a new file called `server.js` with the following content: +## Step 5: Create a new file called `server.js`. + +Add the following content: ```javascript var express = require('express'); @@ -203,7 +205,7 @@ app.listen(8000, function () { }); ``` -### Step 6: Replace the content of the `src/cert_var_assets/src/index.html` with the following content: +## Step 6: Replace the content of the `src/cert_var_assets/src/index.html` with the following: ```html @@ -230,14 +232,14 @@ app.listen(8000, function () { ``` -### Step 7: Start a local web server that hosts the frontend. +## Step 7: Start a local web server that hosts the frontend ```bash npm start ``` -### Step 8: Visit the frontend, and interact with the demo there: +## Step 8: Visit the frontend, and interact with application ```bash http://localhost:8080/ diff --git a/motoko/classes/README.md b/motoko/classes/README.md index 8f3f8d14c..0d3f70416 100644 --- a/motoko/classes/README.md +++ b/motoko/classes/README.md @@ -1,13 +1,5 @@ ---- -keywords: [beginner, motoko, classes, actor classes] ---- - # Classes -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/classes) - -## Overview - This example demonstrates a simple use of actor classes, allowing a program to dynamically install new actors (that is, canisters). It also demonstrates a multi-canister project, and actors using inter-actor communication through shared functions. The example defines two Motoko actors, `Map` and `Test`. @@ -26,29 +18,32 @@ The `Test.mo` actor imports the (installed) `Map` canister, using `Maps` Candid This is a Motoko example that does not currently have a Rust variant. - ## Prerequisites -This example requires an installation of: -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/). +- [x] Install the [IC + SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` Begin by opening a terminal window. -### Step 1: Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the command: +## Step 1: Setup the project environment + +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: + ```bash cd examples/motoko/classes dfx start --background ``` -### Step 2: Deploy the canisters `Map` and `Test`: +## Step 2: Deploy the canisters `Map` and `Test` ```bash -dfx deploy +dfx deploy Map +dfx deploy Test ``` -### Step 3: Invoke the run method of canister Test: +## Step 3: Invoke the run method of canister `Test` ```bash dfx canister call Test run '()' diff --git a/motoko/composite_query/README.md b/motoko/composite_query/README.md index 4b5b69601..025a12da7 100644 --- a/motoko/composite_query/README.md +++ b/motoko/composite_query/README.md @@ -1,13 +1,5 @@ ---- -keywords: [beginner, motoko, composite queries, queries] ---- - # Composite queries -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/composite_query) - -## Overview - This example modifies the simple actor class example to demonstrate the implementation of composite queries. The original example demonstrates a simple use of actor classes, allowing a program to dynamically install new actors (that is, canisters). It also demonstrates a multi-canister project, and actors using inter-actor communication through `shared` functions. @@ -37,38 +29,35 @@ Each new `Bucket` must be provisioned with enough cycles to pay for its installa ## Prerequisites -Verify the following before running this demo: +- [x] Install the [IC + SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -- [x] You have downloaded and installed [dfx](https://sdk.dfinity.org). +Begin by opening a terminal window. -- [x] You have stopped any process that would create a port conflict on `8000`. +## Step 1: Setup the project environment -- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: -## Install - -### Step 1: Start a local internet computer. ```bash -dfx start +cd examples/motoko/composite_query +dfx start --background ``` -### Step 2: Open a new terminal window. - -### Step 3: Deploy the `Map` canister: +## Step 2: Deploy the `Map` canister ```bash -cd examples/motoko/composite_query -dfx deploy +dfx deploy Map ``` -### Step 4: Invoke the `test` method of canister `Map` to add some entries: +## Step 3: Invoke the `test` method of canister `Map` to add some entries ```bash dfx canister call Map test '()' ``` -### Step 5: Observe the following result. +## Step 4: Observe the following result ```bash debug.print: putting: (0, "0") @@ -90,13 +79,13 @@ debug.print: putting: (15, "15") () ``` -### Step 6: Invoke the `get` composite query method of canister `Main`: +## Step 5: Invoke the `get` composite query method of canister `Main` ```bash dfx canister call --query Map get '(15)' ``` -### Step 7: Observe the following result: +### Step 6: Observe the result ```bash (opt "15") diff --git a/motoko/counter/README.md b/motoko/counter/README.md index a48fb5a34..3982192df 100644 --- a/motoko/counter/README.md +++ b/motoko/counter/README.md @@ -1,13 +1,5 @@ ---- -keywords: [beginner, motoko, counter, count] ---- - # Counter -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/counter) - -## Overview - This example demonstrates a counter application. It uses an orthogonally persistent counter variable to store an arbitrary precision natural number that represents the current value of the counter. By using the Motoko keyword stable when declaring the counter variable, the value of this variable will automatically be preserved whenever your canister code is upgraded. Without the stable keyword, a variable is deemed flexible, and its value is reinitialized on every canister upgrade, i.e. whenever new code is deployed to the canister. @@ -26,32 +18,35 @@ This example requires an installation of: Begin by opening a terminal window. - ### Step 1: Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the command: +## Step 1: Setup the project environment + +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: + ```bash cd examples/motoko/counter dfx start --background ``` - ### Step 2: Deploy the canister: +## Step 2: Deploy the canister ```bash dfx deploy ``` - ### Step 3: Set the value of the counter: + ## Step 3: Set the value of the counter ```bash dfx canister call counter set '(7)' ``` - ### Step 4: Increment the value of the counter: +## Step 4: Increment the value of the counter ```bash dfx canister call counter inc ``` - ### Step 5: Get the value of the counter: +## Step 5: Get the value of the counter ```bash dfx canister call counter get @@ -63,7 +58,7 @@ The following output should be returned: (8 : nat) ``` -### Resources +## Resources To learn more about these features of Motoko, see: - [Orthogonal persistence](https://internetcomputer.org/docs/current/motoko/main/motoko#orthogonal-persistence). diff --git a/motoko/encrypted-notes-dapp-vetkd/README.md b/motoko/encrypted-notes-dapp-vetkd/README.md index cbfc0429a..1c2ecec80 100644 --- a/motoko/encrypted-notes-dapp-vetkd/README.md +++ b/motoko/encrypted-notes-dapp-vetkd/README.md @@ -1,11 +1,5 @@ ---- -keywords: [advanced, motoko, encrypted, encrypted notes, notes dapp, vetkeys, vetkd] ---- - # Encrypted notes: vetKD -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/encrypted-notes-dapp-vetkd) - This is a copy of the `encrypted-notes-dapp` example, adapted to use [the proposed vetKD feature](https://github.com/dfinity/interface-spec/pull/158) and add sharing of notes between users. In particular, instead of creating a principal-specific AES key and syncing it across devices (using device-specific RSA keys), the notes are encrypted with an AES key that is derived (directly in the browser) from a note-ID-specific vetKey obtained from the backend canister (in encrypted form, using an ephemeral transport key), which itself obtains it from the vetKD system API. This way, there is no need for any device management in the dapp, plus sharing of notes becomes possible. @@ -24,9 +18,12 @@ This example uses an **insecure** implementation of [the proposed vetKD system A ### Prerequisites +This example requires an installation of: + +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -### Step 1: Choose which implementation to use by setting a respective environment variable. +## Step 1: Choose which implementation to use by setting a respective environment variable. For **Motoko** deployment use: @@ -34,44 +31,34 @@ For **Motoko** deployment use: export BUILD_ENV=motoko ``` -### Step 2: To generate `$BUILD_ENV`-specific files run: +## Step 2: To generate `$BUILD_ENV`-specific files run: ```sh sh ./pre_deploy.sh ``` -### Step 3: [Install dfx](https://sdk.dfinity.org/docs/quickstart/local-quickstart.html). - -Please keep in mind the `dfx` CLI currently only runs on Linux and macOS. - -### Step 4: Install npm packages from the project root: +## Step 3: Install npm packages from the project root: ```sh npm install ``` _Note_: see [Troubleshooting](#troubleshooting) in case of problems. -### Step 5: In case `dfx` was already started before, run the following: +## Step 4: Run in a separate window: ```sh -dfx stop -rm -rf .dfx +dfx start --clean ``` -### Step 6: Run in a separate window: +> ![TIP] +> If you see an error `Failed to set socket of tcp builder to 0.0.0.0:8000`, make sure that the port `8000` is not occupied, e.g., by the previously run Docker command (you might want to stop the Docker daemon whatsoever for this step). -```sh -dfx start --clean -``` -:::info -If you see an error `Failed to set socket of tcp builder to 0.0.0.0:8000`, make sure that the port `8000` is not occupied, e.g., by the previously run Docker command (you might want to stop the Docker daemon whatsoever for this step). -::: -### Step 7: Install a local [Internet Identity (II)](https://wiki.internetcomputer.org/wiki/What_is_Internet_Identity) canister: +## Step 5: Install a local [Internet Identity (II)](https://wiki.internetcomputer.org/wiki/What_is_Internet_Identity) canister: + +> ![TIP] +> If you have multiple `dfx` identities set up, ensure you are using the identity you intend to use with the `--identity` flag. -:::info -If you have multiple `dfx` identities set up, ensure you are using the identity you intend to use with the `--identity` flag. -::: 1. To install and deploy a canister run: ```sh cd examples/motoko/encrypted-notes-dapp-vetkd @@ -83,7 +70,7 @@ If you have multiple `dfx` identities set up, ensure you are using the identity ``` 3. Visit the URL from above and create at least one local internet identity. -### Step 8: Install the vetKD system API canister: +## Step 6: Install the vetKD system API canister: 1. Ensure the Canister SDK (dfx) uses the canister ID that is hard-coded in the backend canister Rust source code: ```sh dfx canister create vetkd_system_api --specified-id s55qq-oqaaa-aaaaa-aaakq-cai @@ -93,27 +80,30 @@ If you have multiple `dfx` identities set up, ensure you are using the identity dfx deploy vetkd_system_api ``` -### Step 9:. Deploy the encrypted notes backend canister: +## Step 7: Deploy the encrypted notes backend canister: ```sh dfx deploy "encrypted_notes_$BUILD_ENV" ``` -⚠️ Before deploying the Rust canister, you should first run `rustup target add wasm32-unknown-unknown`. -### Step 10: Update the generated canister interface bindings: +> [!WARNING] +> Before deploying the Rust canister, you should first run `rustup target add wasm32-unknown-unknown`. + +## Step 8: Update the generated canister interface bindings: ```sh dfx generate "encrypted_notes_$BUILD_ENV" ``` -### Step 11: Deploy the frontend canister: +## Step 9: Deploy the frontend canister: + ```sh dfx deploy www ``` -You can check its URL with `npm run print-dfx-www`. +You can check its URL with `npm run print-dfx-www`. -### Step 11: Open the frontend: +### Step 10: Open the frontend: 1. Start the local development server, which also supports hot-reloading: ```sh @@ -121,9 +111,9 @@ You can check its URL with `npm run print-dfx-www`. ``` 2. Open the URL that is printed in the console output. Usually, this is [http://localhost:3000/](http://localhost:3000/). -:::info -If you have opened this page previously, please remove all local store data for this page from your web browser, and hard-reload the page. For example in Chrome, go to Inspect → Application → Local Storage → `http://localhost:3000/` → Clear All, and then reload. -::: +> [!TIP] +> If you have opened this page previously, please remove all local store data for this page from your web browser, and hard-reload the page. For example in Chrome, go to Inspect → Application → Local Storage → `http://localhost:3000/` → Clear All, and then reload. + ## Troubleshooting diff --git a/motoko/encrypted-notes-dapp/README.md b/motoko/encrypted-notes-dapp/README.md index b59aee1b8..39340faea 100644 --- a/motoko/encrypted-notes-dapp/README.md +++ b/motoko/encrypted-notes-dapp/README.md @@ -1,11 +1,5 @@ ---- -keywords: [advanced, motoko, encrypted notes, encrypted, notes dapp] ---- - # Encrypted notes -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/encrypted-notes-dapp) - Encrypted notes is an example dapp for authoring and storing confidential information on the Internet Computer (ICP) in the form of short pieces of text. Users can create and access their notes via any number of automatically synchronized devices authenticated via [Internet Identity (II)](https://wiki.internetcomputer.org/wiki/What_is_Internet_Identity). Notes are stored confidentially thanks to the end-to-end encryption performed by the dapp’s frontend. This project serves as a simple (but not too simple) example of a dapp, which uses Motoko and Rust as backend and Svelte as frontend. @@ -33,8 +27,6 @@ This is an **example dapp** that demonstrates the potential of building **canist ---   -## Overview - You can play around with the [dapp deployed on ICP](https://cvhrw-2yaaa-aaaaj-aaiqa-cai.icp0.io/) and see a quick introduction on [YouTube](https://youtu.be/DZQmtPSxvbs). We wanted to build an example of a simple (but not too simple) dapp running purely on the IC. This example relies upon the **web-serving** and **storage capabilities** of the IC. We focused on the following two key features for our example dapp: @@ -108,12 +100,15 @@ Once authenticated with II: Follow the steps below to deploy this sample project. -## Prerequisites -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index). +### Prerequisites +This example requires an installation of: + +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` - [x] Download and install [Docker](https://docs.docker.com/get-docker/) if using the Docker option. -- [x] Download the GitHub repo containing this project's files: `git clone https://github.com/dfinity/examples` -### Step 1. Navigate inside of the project's folder: + +## Step 1: Navigate inside of the project's folder ```bash cd examples/motoko/encrypted-notes-dapp @@ -121,7 +116,7 @@ cd examples/motoko/encrypted-notes-dapp This project folder contains the files for both Motoko and Rust development. -### Step 2: Set an environmental variable reflecting which backend canister you'll be using: +## Step 2: Set an environmental variable reflecting which backend canister you'll be using For Motoko deployment run: @@ -132,7 +127,7 @@ export BUILD_ENV=motoko **Building the Rust canister requires either the Rust toolchain installed on your system or Docker-backed deployment (see below).** -### Step 3: Deploy locally. +## Step 3: Deploy locally ### Option 1: Docker deployment **This option does not yet work on Apple M1; the combination of DFX and Docker do not currently support the required architecture.** @@ -188,15 +183,14 @@ dfx start ``` -:::info -If you see an error "Failed to set socket of tcp builder to 0.0.0.0:8000", make sure that the port 8000 is not occupied, e.g., by the previously run Docker command (you might want to stop the Docker daemon whatsoever for this step). -::: +> [!TIP] +> If you see an error "Failed to set socket of tcp builder to 0.0.0.0:8000", make sure that the port 8000 is not occupied, e.g., by the previously run Docker command (you might want to stop the Docker daemon whatsoever for this step). + - #### Step 5: Install a local Internet Identity (II) canister. -:::info -If you have multiple `dfx` identities set up, ensure you are using the identity you intend to use with the `--identity` flag. -::: +> [!TIP] +> If you have multiple `dfx` identities set up, ensure you are using the identity you intend to use with the `--identity` flag. To install and deploy a canister run: @@ -246,12 +240,10 @@ npm run dev ``` -:::caution -If you have opened this page previously, please remove all local store data for this page from your web browser, and hard-reload the page. - -For example in Chrome, go to Inspect → Application → Local Storage → http://localhost:3000/ → Clear All, and then reload. -::: - +> [!WARNING] +> If you have opened this page previously, please remove all local store data for this page from your web browser, and hard-reload the page. +> +> For example in Chrome, go to Inspect → Application → Local Storage → http://localhost:3000/ → Clear All, and then reload. ### Mainnet deployment @@ -341,7 +333,7 @@ Fig. 3. Scenario for a user with multiple registered devices. - #### Step 1: Perform steps 1-3 of Scenario I on Device A. -- #### Step 2:. Perform steps 1-3 of Scenario I on Device B. +- #### Step 2: Perform steps 1-3 of Scenario I on Device B. One subtle difference that you might observe on Device B is that the message "Synchronizing..." (Fig. 3(a)) appears for a short time. As Device A was the first to log in, it was also the first one to generate a shared secret. Device B has to retrieve it. To do that, Device B first uploads its public key (pub B) to the backend canister. Device A retrieves pub B using periodic polling. Device A then re-encrypts the shared secret with pub B and uploads it to the backend. Afterward, Device B can retrieve the encrypted shared secret and decrypt it with its private key. @@ -409,6 +401,7 @@ Observer `All tests passed.` at the end of the output. ## Troubleshooting + ### Building/deployment problems Error `ERR_OSSL_EVP_UNSUPPORTED`. Version 17+ of node.js introduces changes to the way Node handles OpenSSL. diff --git a/motoko/hello_cycles/README.md b/motoko/hello_cycles/README.md index bf3340cfe..430e2fadc 100644 --- a/motoko/hello_cycles/README.md +++ b/motoko/hello_cycles/README.md @@ -1,13 +1,5 @@ ---- -keywords: [beginner, motoko, hello, hello cycles, cycles] ---- - # Hello, cycles! -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/hello_cycles) - -## Overview - The `hello_cycle`s sample project provides a simple example to illustrate how you might add functions to receive cycles, transfer cycles, and check your cycle balance with a simple Motoko actor (canister). This sample project assumes that you are using the default cycles wallet canister that is created for you. @@ -26,28 +18,31 @@ The wallet's `wallet_receive` return type differs from hello_cycle's `wallet_rec This is a Motoko example that does not currently have a Rust variant. -## Prerequisites +### Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). -- [x] Download the following project files from GitHub: `git clone https://github.com/dfinity/examples` +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` Begin by opening a terminal window. -### Step 1: Navigate into the folder containing the project's files and start a local instance of the replica with the command: +## Step 1: Setup the project environment + +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: + ```bash cd examples/motoko/hello_cycles dfx start --background ``` -### Step 2: Deploy the canister: +## Step 2: Deploy the canister ```bash dfx deploy ``` -### Step 3: Check that the current cycles balance of canister hello_cycles by running the following command: +## Step 3: Check that the current cycles balance of the `hello_cycles` canister ```bash dfx canister call hello_cycles wallet_balance @@ -59,7 +54,7 @@ The output should resemble the following: (3_091_662_816_985 : nat) ``` -You can also see the cycles balance of hello_cycles (or any canister you control) by calling: +You can also see the cycles balance of `hello_cycles` (or any canister you control) by calling: ```bash dfx canister status hello_cycles @@ -79,7 +74,7 @@ Balance: 3_092_278_099_590 Cycles Module hash: 0x09198be65e161bdb5c75c705dfec4b707a8091ac5d1a095dd45c025142a1fc43 ``` -### Step 4: To display the default wallet and hello_cycles canister principals, run the commands: +## Step 4: Display the default wallet and hello_cycles canister principals ```bash dfx identity get-wallet @@ -95,7 +90,7 @@ dzh22-nuaaa-aaaaa-qaaoa-cai Below, we'll frequently use `$(dfx identity get-wallet)` and `$(dfx canister id hello_cycles)` to splice canister principals into longer bash commands. -### Step 5: Attempt to send 2 trillion cycles from the default wallet to the hello_cycles canister by running the following command: +## Step 5: Attempt to send 2 trillion cycles from the default wallet to the hello_cycles canister ```bash dfx canister call $(dfx identity get-wallet) wallet_send "(record { canister = principal \"$(dfx canister id hello_cycles)\"; amount = (2000000000000:nat64); } )" @@ -109,7 +104,7 @@ If successful, the output will look similar to: (variant { 17_724 }) ``` -#### Step 6: Verify that the cycles balance for the hello_cycles canister has increased by 10_000_000 by running the following command: +## Step 6: Verify that the cycles balance for the hello_cycles canister has increased by 10_000_000 ```bash dfx canister call hello_cycles wallet_balance @@ -123,7 +118,7 @@ Output: The amount is only increased by 10_000_000 because the implementation of `wallet_receive` is coded to accept at most 10_000_000 cycles, even when more cycles were transferred with the call. The unaccepted cycles are not lost but implicitly refunded to the caller (in this case, the wallet). -### Step 7: Send some cycles from the hello_cycles canister back to the wallet by running the command: +## Step 7: Send some cycles from the hello_cycles canister back to the wallet ```bash dfx canister call hello_cycles transfer "(func \"$(dfx identity get-wallet)\".\"wallet_receive\", 5000000)" @@ -135,7 +130,7 @@ Output: (record { refunded = 0 : nat }) ``` -### Step 8: Verify that the cycles balance of the `hello_cycles` canister has decreased with: +## Step 8: Verify that the cycles balance of the `hello_cycles` canister has decreased ```bash dfx canister call hello_cycles wallet_balance diff --git a/motoko/ic-pos/README.md b/motoko/ic-pos/README.md index cea9d3ddc..aba1d5dc7 100644 --- a/motoko/ic-pos/README.md +++ b/motoko/ic-pos/README.md @@ -1,7 +1,3 @@ ---- -keywords: [advanced, motoko, bitcoin, pos, point of sale, ckbtc] ---- - # IC-POS ![](./media/header.png) @@ -54,14 +50,14 @@ The frontend interacts with the following IC canisters: - `ckbtc index` - to fetch transaction history. - `internet identity` - to authenticate users. -## Setup, dev environment +### Prerequisites +This example requires an installation of: + +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -Pre-requisites: +Begin by opening a terminal window. -- [Local Internet Computer dev environment](https://internetcomputer.org/docs/current/developer-docs/backend/rust/dev-env) -- [Node 20+](https://nodejs.org/en/) -- [pnpm](https://pnpm.io/installation) - ## Deploy using script To get started quickly and deploy the IC-POS app locally, you can run a deploy script. This script will start a local replica, deploy the necessary canisters, and build and deploy the frontend. @@ -74,21 +70,17 @@ Once the script has finished, you should proceed to step 10 to create a store an ## Deploy manually -### 1. Clone the examples repository and navigate to the IC-POS project: +### Step 1: Setup the project environment -```bash -git clone https://github.com/dfinity/examples -cd examples/motoko/ic-pos -``` +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: -### 2. Start a local instance of the replica: - ```bash -dfx start --clean --background +cd examples/motoko/ic-pos +dfx start --background ``` -### 3. Deploy the Internet Identity canister: +### Step 2: Deploy the Internet Identity canister Integration with the [Internet Identity](https://internetcomputer.org/internet-identity/) allows store owners to securely setup and manage their store. The Internet Identity canister is already deployed on the IC mainnet. For local development, you need to deploy it to your local instance of the IC. @@ -96,7 +88,7 @@ Integration with the [Internet Identity](https://internetcomputer.org/internet-i dfx deploy internet_identity ``` -### 4. Save the current principal as a variable: +### Step 3: Save the current principal as a variable The principal will be used when deploying the ledger canister. @@ -104,7 +96,7 @@ The principal will be used when deploying the ledger canister. export OWNER=$(dfx identity get-principal) ``` -### 5. Deploy the ckBTC ledger canister: +### Step 4: Deploy the ckBTC ledger canister The responsibilities of the ledger canister is to keep track of token balances and handle token transfers. @@ -147,7 +139,7 @@ dfx deploy icrc1_ledger --argument ' ' ``` -### 6. Deploy the index canister +### Step 5: Deploy the index canister The index canister syncs the ledger transactions and indexes them by account. @@ -159,7 +151,7 @@ dfx deploy icrc1_index --argument ' ' ``` -### 7. Deploy the icpos canister +### Step 6: Deploy the `icpos` canister The icpos canister manages the store configuration and sends notifications when a payment is received. @@ -169,7 +161,7 @@ The `--argument '(0)'` argument is used to initialize the canister with `startBl dfx deploy icpos --argument '(0)' ``` -### 8. Configure the icpos canister +### Step 7: Configure the `icpos` canister IC-POS uses [Courier](https://courier.com/) to send email and SMS notifications. If you want to enable notifications, you need to sign up for a Courier account and and create and API key. Then issue the following command: @@ -177,7 +169,7 @@ IC-POS uses [Courier](https://courier.com/) to send email and SMS notifications. dfx canister call icpos setCourierApiKey "pk_prod_..." ``` -### 9. Build and run the frontend +### Step 8: Build and run the frontend Run npm to install dependencies and start a development version of the frontend. @@ -188,15 +180,13 @@ pnpm run dev The app should now be accessible at a local url, typically `http://localhost:5173`. -### 10. Make a transfer! - - +## Make a transfer! Now that everything is up and running, you can make a transfer to your newly created store. The easiest way to do this is to create two stores using two different Internet Identity accounts, using two different web browsers. Then, transfer some tokens from one store to the other. -#### 10.1 Create the first store and supply it with some tokens +### Step 10: Create the first store and supply it with some tokens Log in to the frontend using the Internet Identity. Configure the store with a name and then, on the main store page, click on the principal pill to copy the address to your clipboard. Using the `dfx` command, now mint some tokens from your owner principal to the store principal. @@ -211,7 +201,7 @@ dfx canister call icrc1_ledger icrc1_transfer ' ' ``` -#### 10.2 Create the second store +### Step 11: Create the second store Log in to the frontend using **a new Internet Identity using another web browser**. Give this store a name as well and copy the store principal like in the previous step. diff --git a/motoko/icrc2-swap/README.md b/motoko/icrc2-swap/README.md index 45b5cf660..6c4fd1efd 100644 --- a/motoko/icrc2-swap/README.md +++ b/motoko/icrc2-swap/README.md @@ -1,13 +1,5 @@ ---- -keywords: [advanced, motoko, swap, token swap, icrc2] ---- - # ICRC-2 swap -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/icrc2-swap) - -## Overview - ICRC-2 Swap is a simple canister demonstrating how to safely work with ICRC-2 tokens. It handles depositing, swapping, and withdrawing ICRC-2 tokens. @@ -27,19 +19,24 @@ different from other synchronous blockchains. ## Local deployment -## Prerequisites +### Prerequisites +This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). -- [x] Install [Node.js](https://nodejs.org/en/). -- [ ] Clone the example dapp project: `git clone https://github.com/dfinity/examples` +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` + +Begin by opening a terminal window. + +### Step 1: Setup the project environment -### Step 1: Start a local instance of the replica: +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: ```bash -dfx start --clean --background +cd examples/motoko/icrc2-swap +dfx start --background ``` -### Step 2: Create your user accounts: +### Step 2: Create your user accounts ```bash export OWNER=$(dfx identity get-principal) @@ -51,7 +48,7 @@ dfx identity new bob export BOB=$(dfx identity get-principal --identity bob) ``` -### Step 2: Deploy two tokens: +### Step 3: Deploy two tokens Deploy Token A: @@ -122,7 +119,7 @@ dfx deploy token_b --argument ' ' ``` -### Step 3: Deploy the swap canister: +### Step 4: Deploy the swap canister The swap canister accepts deposits and performs the swap. @@ -140,7 +137,7 @@ dfx deploy swap --argument ' export SWAP=$(dfx canister id swap) ``` -### Step 4: Approve & deposit tokens: +### Step 5: Approve & deposit tokens Before you can swap the tokens, they must be transferred to the swap canister. With ICRC-2, this is a two-step process. First, approve the transfer: @@ -199,7 +196,7 @@ dfx canister call --identity bob swap deposit 'record { }' ``` -### Step 5: Perform a swap: +### Step 6: Perform a swap ```bash dfx canister call swap swap 'record { @@ -217,7 +214,7 @@ dfx canister call swap balances That should show us that now Bob holds Token A, and Alice holds Token B in the swap contract. -### Step 6: Withdraw tokens: +### Step 7: Withdraw tokens After the swap, your balances in the swap canister will have been updated, and you can withdraw your newly received tokens into your wallet. @@ -244,7 +241,7 @@ dfx canister call --identity bob swap withdraw 'record { }' ``` -### Step 7: Check token balances: +### Step 8: Check token balances ```bash # Check Alice's Token A balance. They should now have 998.99980000 A @@ -268,24 +265,31 @@ the token balances. The example comes with a test suite to demonstrate the basic functionality. It shows how to use this repo from a Javascript client. -## Prerequisites +### Prerequisites +This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). -- [x] Install [Node.js](https://nodejs.org/en/). +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` + +Begin by opening a terminal window. + +### Step 1: Setup the project environment + +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: -### Step 1: Start a local instance of the replica: ```bash -dfx start --clean --background +cd examples/motoko/icrc2-swap +dfx start --background ``` -### Step 2: Install npm dependencies: +### Step 2: Install npm dependencies ```bash npm install ``` -### Step 3: Run the test suite: +### Step 3: Run the test suite ```bash make test diff --git a/motoko/internet_identity_integration/README.md b/motoko/internet_identity_integration/README.md index 271d759e9..8626b1754 100644 --- a/motoko/internet_identity_integration/README.md +++ b/motoko/internet_identity_integration/README.md @@ -1,13 +1,5 @@ ---- -keywords: [intermediate, motoko, internet identity, authentication] ---- - # Internet Identity integration -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/internet_identity_integration) - -## Overview - This tutorial shows how to integrate Internet Identity into a dapp front-end and make use of the user identity in the backend. It builds on the "greet" dapp that is generated by running `dfx new`. If you are unfamiliar with `dfx new` and the generated application, please have a look at [this](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx) guide first. The code contained in this folder shows the finished solution you should arrive at after following the step-by-step instructions. @@ -17,24 +9,28 @@ This tutorial will explain all the steps required to integrate the default start - Offer a login with Internet Identity button. - Greet you with the principal provided by Internet Identity instead of entering a name. -This is a Motoko example that does not currently have a Rust variant. +This is a Motoko example that does not currently have a Rust variant. +### Prerequisites +This example requires an installation of: -## Prerequisites - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). -- [x] Install [Node.js](https://nodejs.org/en/download/). +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` - [x] Download and install the `@dfinity/auth-client` package with the command `npm install @dfinity/auth-client`. -- [x] Download the following project files from GitHub: `git clone https://github.com/dfinity/examples` - [x] Chrome or Firefox browser (other browsers also work, but may need a slightly different webpack configuration, see the note on [step 4 below](#step-4-make-the-internet-identity-url-available-in-the-build-process)) -### Step 1: Navigate into the examples folder for this sample and then generate a new project with `dfx new`: +Begin by opening a terminal window. + +## Step 1: Setup the project environment + +Navigate into the folder containing the project's files, start a local instance of the Internet Computer, and create a new project with the commands: ```bash cd examples/motoko/internet_identity_integration +dfx start --background dfx new greet ``` - You should have a starter project generated with the following file structure: ```bash @@ -56,7 +52,8 @@ You should have a starter project generated with the following file structure: └── webpack.config.js ``` -### Step 2: Add Internet Identity to the local project. +## Step 2: Add Internet Identity to the local project + Add this code block to the canister section in the `dfx.json` file: **The following example is a **code snippet** that is part of a larger code file. This snippet may return an error if run on its own. To view the full code file that should be run, please see [final code](#final-code).** @@ -77,7 +74,8 @@ Add this code block to the canister section in the `dfx.json` file: This adds a prebuilt Internet Identity canister to your project. The remote property makes sure, that this canister is only deployed locally (as it already exists on mainnet). The frontend property tells `dfx` that this canister does have a front-end (so it prints the front-end URL after deployment, see the next step). The URLs point to the latest dev build release of Internet Identity. The dev build has some extra features that make Internet Identity easier to use in a development setting (such as a predictable captcha, no requirement for WebAuthn, etc.). -### Step 3: Deploy Internet Identity locally. +## Step 3: Deploy Internet Identity locally + Run `dfx deploy` to deploy all canisters including Internet Identity to the local replica. It should print the Internet Identity URL to the console: ```bash @@ -99,7 +97,8 @@ URLs: Open the `internet_identity` link in the browser. You should be able to create anchors and register devices. -### Step 4: Make the Internet Identity URL available in the build process. +## Step 4: Make the Internet Identity URL available in the build process + We want the sample application to integrate with Internet Identity differently depending on whether we deploy locally or on mainnet: - Locally the application should use the Internet Identity URL `http://.localhost:4943/`. @@ -249,14 +248,14 @@ module.exports = { }; ``` -### Step 5: Add the auth-client library to the frontend. +## Step 5: Add the auth-client library to the frontend The auth-client is a library provided by DFINITY to make integration with Internet Identity easy. Run: ```bash npm install @dfinity/auth-client @dfinity/identity --save-dev ``` -### Step 6: Add a login button to the frontend. +## Step 6: Add a login button to the frontend Open the `index.html` file and replace the content with the following: ```html @@ -288,7 +287,7 @@ Open the `index.html` file and replace the content with the following: ``` -### Step 7: Make the login button interact with II. +## Step 7: Make the login button interact with II In order for the login button to work, we need to give it behavior. Replace the contents of the `src/greet_frontend/src/index.js` file with the following: ```javascript @@ -342,7 +341,7 @@ loginButton.onclick = async (e) => { };% ``` -### Step 8: Modify the backend. +## Step 8: Modify the backend We want our application to greet the caller principal. To do so, the backend Motoko code needs to be changed to: - No longer take a name parameter. @@ -360,7 +359,9 @@ actor { }; ``` -### Step 9: Run `dfx deploy` again. This will also regenerate the bindings in `src/declarations`. +## Step 9: Run `dfx deploy` again + +This will also regenerate the bindings in `src/declarations`. The successful output should resemble the following: @@ -375,7 +376,7 @@ URLs: internet_identity: http://127.0.0.1:4943/?canisterId=gf4a7-g4aaa-aaaaa-qaarq-cai&id=g6z42-4eaaa-aaaaa-qaata-cai ``` -### Step 10: Test the application. +## Step 10: Test the application Open the `greet_frontend` URL in a web browser. diff --git a/motoko/life/README.md b/motoko/life/README.md index 55d2e3f0e..00e9aa435 100644 --- a/motoko/life/README.md +++ b/motoko/life/README.md @@ -1,13 +1,5 @@ ---- -keywords: [beginner, motoko, game of life] ---- - # Game of life -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/life) - -## Overview - This example contains a series of implementations of Conway's Game of Life. Its main purpose is to demonstrate state-preserving upgrades using Motoko's stable variables. The implementations are meant to be instructive and are not optimized for efficiency or to hide network latency, which a production implementation would need to consider. @@ -22,24 +14,24 @@ To make upgrades apparent, each version uses a different digit to display live c This is a Motoko example that does not currently have a Rust variant. - -## Prerequisites +### Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). -- [x] Install [Node.js](https://nodejs.org/en/download/). - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` Begin by opening a terminal window. -### Step 1: Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the command: +## Step 1: Setup the project environment + +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: ```bash cd examples/motoko/life dfx start --background ``` -### Step 2: Deploy the canister: +## Step 2: Deploy the canisters ```bash dfx deploy @@ -53,7 +45,7 @@ Take note of the URL at which the life_assets is accessible using the command: echo "http://127.0.0.1:4943/?canisterId=$(dfx canister id life_assets)" ``` -### Step 3: Open the frontend in your browser by clicking on the link returned in the output of the previous command. +## Step 3: Open the frontend in your browser by clicking on the link returned in the output of the previous command. Click the button **Step**. The grid will advance to the next generation of the Game of Life. @@ -131,7 +123,7 @@ After first upgrading from v0 the state will be random, as on deploying v0. This However, if you re-deploy the v1 project a second time, perhaps after making a minor edit, you'll see the last state of the grid, before deployment, preserved across the deployment, in a state-preserving upgrade. The random initializer for state is skipped and state just assumes the value it had before the upgrade. -### Upgrading to v2: +### Upgrading to v2 To upgrade to the v2 implementation, issue these commands: ```bash diff --git a/motoko/minimal-counter-dapp/README.md b/motoko/minimal-counter-dapp/README.md index fb30764e4..43239413b 100644 --- a/motoko/minimal-counter-dapp/README.md +++ b/motoko/minimal-counter-dapp/README.md @@ -1,15 +1,7 @@ ---- -keywords: [beginner, motoko, counter] ---- - # Minimal counter dapp -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/minimal-counter-dapp) - ![Counter Frontend](README_images/frontend.png) -## Overview - The example dapp shows how to build a very basic dapp with both backend and frontend, using Motoko for the backend functionality and plain HTML and JavaScript for the frontend. The dapp is a simple counter, which will increment, decrement or reset a counter by clicking a button in the frontend. The purpose of this example dapp is to build a minimalistic dapp, based on the default dapp template, installed by `dfx` when creating a new project. @@ -18,31 +10,29 @@ This example covers: - Create a new canister smart contract using the IC SDK (`dfx`). - Use the default project as a template as the starting point for the new project. -- Add backend functions for a counter (increment, getCount, decreent and reset). +- Add backend functions for a counter (increment, getCount, decrement and reset). - Implement backend functions in the frontend. - Deploy the canister smart contract locally. - Test backend with Candid UI and command line using `dfx`, and test frontend in browser. -## Prerequisites - +### Prerequisites This example requires an installation of: -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). -- [x] Install [Node.js](https://nodejs.org/en/download/). -- [x] Download and install [git.](https://git-scm.com/downloads) +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` Begin by opening a terminal window. -### Step 1: Navigate into the folder containing the project's files and start a local instance of the replica with the command: +## Step 1: Setup the project environment + +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: ```bash cd examples/motoko/minimal-counter-dapp -npm install dfx start --background ``` -### Step 2: Build and deploy the canister: +## Step 2: Build and deploy the canister ```bash dfx deploy @@ -61,7 +51,7 @@ URLs: minimal_dapp_backend: http://127.0.0.1:4943/?canisterId=be2us-64aaa-aaaaa-qaabq-cai&id=bkyz2-fmaaa-aaaaa-qaaaq-cai ``` -### Step 3: Open the `minimal_dapp_frontend` URL in a web browser. +## Step 3: Open the `minimal_dapp_frontend` URL in a web browser You will see a GUI interface with following buttons: @@ -76,7 +66,6 @@ The three main parts of the example dapp are the backend, the Candid interface, ### Motoko backend The backend functions are located in the `src/minimal_dapp_backend/main.mo` Motoko file. The backend stores the counter value and has functions to get, increment, decrement and reset the counter value. - #### Counter variable Four functions are created to make the counter work: `increment()`, `decrement()`, `getCount()` and `reset()`. The current counter value is stored as a number in the actor. diff --git a/motoko/parallel_calls/README.md b/motoko/parallel_calls/README.md index e91d06c3b..51e2a5858 100644 --- a/motoko/parallel_calls/README.md +++ b/motoko/parallel_calls/README.md @@ -1,13 +1,5 @@ ---- -keywords: [advanced, motoko, defi] ---- - # Parallel inter-canister calls -[View this sample code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/parallel_calls). - -## Overview - This example demonstrates how to implement inter-canister calls that run in parallel in Motoko, and highlights some differences between parallel and sequential calls. Running independent calls in parallel can lower the latency, especially when messages are sent across subnets. For example, a canister that swaps two tokens might want to launch both token transfer operations in parallel. ## Architecture @@ -18,38 +10,38 @@ The sample code revolves around two simple canisters, `caller` and `callee`. `Ca The callee exposes a simple `ping` endpoint that takes no parameters and returns nothing. -## Prerequisites - -To run this example you should: +### Prerequisites +This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -## Running the example - Begin by opening a terminal window. -### Step 1: Navigate into the example folder and start a local Internet Computer replica +## Step 1: Setup the project environment + +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: ```bash cd examples/motoko/parallel_calls dfx start --background ``` -### Step 2: Deploy the canister +## Step 2: Deploy the canisters ```bash dfx deploy ``` -### Step 3: Set up the caller canister +## Step 3: Set up the caller canister We now provide the ID of the callee to the caller, such that the caller can initiate calls. + ``` dfx canister call caller setup_callee "(principal \"`dfx canister id callee`\")" ``` -### Step 4: Invoke sequential and parallel calls +## Step 4: Invoke sequential and parallel calls Let's first call the different endpoints of the `caller` canister using `dfx` @@ -68,7 +60,7 @@ And the other endpoint: dfx canister call caller parallel_calls 100 ``` -which outputs: +This should output: ```bash (100 : nat64) @@ -102,7 +94,7 @@ All the sequential calls succeed, but most parallel calls fail. The reason is th Lastly, the parallel calls here complete sooner -- because most of them fail! -### Step 5: Multi-subnet setting +## Step 5: Multi-subnet setting Parallel calls are a lot more useful in multi-subnet settings. We can create such a setting locally using Pocket IC. diff --git a/motoko/pub-sub/README.md b/motoko/pub-sub/README.md index 8ce86d03f..683e88581 100644 --- a/motoko/pub-sub/README.md +++ b/motoko/pub-sub/README.md @@ -1,18 +1,10 @@ ---- -keywords: [beginner, motoko, pubsub, publish, subscribe] ---- - # PubSub -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/pub-sub) - - -## Overview This sample project demonstrates how functions may be passed as arguments of inter-canister calls to be used as callbacks. A common problem in both distributed and decentralized systems is keeping separate services (or canisters) synchronized with one another. While there are many potential solutions to this problem, a popular one is the publisher/subscriber pattern or "PubSub". PubSub is an especially valuable pattern on the Internet Computer as its primary drawback, message delivery failures, does not apply. -## Prerequisites +### Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). @@ -20,32 +12,34 @@ This example requires an installation of: Begin by opening a terminal window. -### Step 1: Navigate into the folder containing the project's files and start a local instance of the replica with the command: +## Step 1: Setup the project environment + +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: ```bash cd examples/motoko/pub-sub dfx start --background ``` -### Step 2: Deploy the canister: +## Step 2: Deploy the canisters: ```bash dfx deploy ``` -### Step 3: Subscribe to the "Apples" topic: +## Step 3: Subscribe to the "Apples" topic ```bash dfx canister call sub init '("Apples")' ``` -### Step 4: Publish to the "Apples" topic: +## Step 4: Publish to the "Apples" topic ```bash dfx canister call pub publish '(record { "topic" = "Apples"; "value" = 2 })' ``` -### Step 5: Receive your subscription: +## Step 5: Receive your subscription ```bash dfx canister call sub getCount diff --git a/motoko/random_maze/README.md b/motoko/random_maze/README.md index ba484e796..65714318b 100644 --- a/motoko/random_maze/README.md +++ b/motoko/random_maze/README.md @@ -1,13 +1,5 @@ ---- -keywords: [beginner, motoko, random, randomness, maze, game] ---- - # Random maze -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/random_maze) - -## Overview - The example generates a random maze using cryptographic randomness. It illustrates: @@ -26,7 +18,7 @@ The function `generate` calls library function `Random.blob()` asynchronously to This is a Motoko example that does not currently have a Rust variant. -## Prerequisites +### Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). @@ -34,26 +26,28 @@ This example requires an installation of: Begin by opening a terminal window. -### Step 1: Navigate into the folder containing the project's files and start a local instance of the replica with the command: +## Step 1: Setup the project environment + +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: ```bash cd examples/motoko/random_maze dfx start --background ``` -### Step 2: Install front-end dependencies: +## Step 2: Install front-end dependencies ```bash npm install ``` -### Step 3: Deploy the canister: +## Step 3: Deploy the canisters ```bash dfx deploy ``` -### Step 4: Take note of the URL at which the user interface is accessible. +## Step 4: Take note of the URL at which the user interface is accessible ```bash echo "http://127.0.0.1:4943/?canisterId=$(dfx canister id random_maze_assets)" diff --git a/motoko/send_http_get/README.md b/motoko/send_http_get/README.md index 064445c2a..9e6d80a8d 100644 --- a/motoko/send_http_get/README.md +++ b/motoko/send_http_get/README.md @@ -1,11 +1,5 @@ ---- -keywords: [intermediate, motoko, http get, http, get] ---- - # HTTP: GET -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/send_http_get) - The purpose of this dapp is to give developers a minimal dapp that uses the IC's HTTPS outcalls feature to make a `GET` request. This demo goes in hand with the [developer documentation on HTTPS outcalls](https://internetcomputer.org/docs/current/developer-docs/integrations/https-outcalls/https-outcalls-get). @@ -15,18 +9,6 @@ If you want to start working on your project right away, you might want to try t ```bash git clone https://github.com/dfinity/examples cd examples/motoko/send_http_get -dfx help -dfx canister --help -``` - -## Running the project locally -If you want to test your project locally, you can use the following commands: - -```bash -# Starts the replica, running in the background dfx start --background - -# Deploys your canisters to the replica and generates your candid interface dfx deploy ``` - diff --git a/motoko/send_http_post/README.md b/motoko/send_http_post/README.md index bb2faf180..bfa2b865c 100644 --- a/motoko/send_http_post/README.md +++ b/motoko/send_http_post/README.md @@ -1,11 +1,5 @@ ---- -keywords: [intermediate, motoko, http post, post, http] ---- - # HTTP: POST -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/send_http_post) - The purpose of this dapp is to give developers a minimal dapp that uses the IC's HTTPS outcalls feature to make a `POST` request. This demo goes in hand with the [developer documentation on HTTPS outcalls](https://internetcomputer.org/docs/current/developer-docs/integrations/https-outcalls/https-outcalls-post). @@ -15,18 +9,6 @@ If you want to start working on your project right away, you might want to try t ```bash git clone https://github.com/dfinity/examples cd examples/motoko/send_http_post_motoko -dfx help -dfx canister --help -``` - -## Running the project locally - -If you want to test your project locally, you can use the following commands: - -```bash -# Starts the replica, running in the background dfx start --background - -# Deploys your canisters to the replica and generates your candid interface dfx deploy ``` diff --git a/motoko/superheroes/README.md b/motoko/superheroes/README.md index b737eb081..3ea4b6122 100644 --- a/motoko/superheroes/README.md +++ b/motoko/superheroes/README.md @@ -1,18 +1,10 @@ ---- -keywords: [advanced, motoko, crud, crud application] ---- - # CRUD example -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/superheroes) - -## Overview - This example demonstrates how to build a CRUD application on ICP using Motoko and React. This is a Motoko example that does not currently have a Rust variant. -## Prerequisites +### Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). @@ -20,32 +12,28 @@ This example requires an installation of: Begin by opening a terminal window. -### Step 1: Navigate into the folder containing the project's files and start a local instance of the replica with the command: +## Step 1: Setup the project environment + +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: ```bash cd examples/motoko/superheroes dfx start --background ``` -### Step 2: Build the frontend of the application: - -```bash -npm install -``` - -### Step 3: Deploy the canister: +## Step 2: Deploy the canisters ```bash dfx deploy ``` -### Step 4: Take note of the URL at which the canister is accessible. +## Step 3: Take note of the URL at which the canister is accessible ```bash echo "http://127.0.0.1:4943/?canisterId=$(dfx canister id www)" ``` -### Step 5: Open the aforementioned URL in your web browser. +## Step 4: Open the aforementioned URL in your web browser. ## Security considerations and best practices diff --git a/motoko/threshold-ecdsa/README.md b/motoko/threshold-ecdsa/README.md index 13e24ae38..f72dd7aae 100644 --- a/motoko/threshold-ecdsa/README.md +++ b/motoko/threshold-ecdsa/README.md @@ -1,13 +1,5 @@ ---- -keywords: [advanced, motoko, threshold ecdsa, signature, ecdsa] ---- - # Threshold ECDSA sample -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/threshold-ecdsa) - -## Overview - We present a minimal example canister smart contract for showcasing the [threshold ECDSA](https://internetcomputer.org/docs/current/developer-docs/integrations/t-ecdsa) API. The example canister is a signing oracle that creates ECDSA signatures with keys derived from an input string. @@ -20,32 +12,35 @@ More specifically: This tutorial gives a complete overview of the development, starting with downloading the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/index.md), up to the deployment and trying out the code on the IC mainnet. -:::info -This walkthrough focuses on the version of the sample canister code written in [Motoko](https://internetcomputer.org/docs/current/developer-docs/backend/motoko/index.md) programming language, but no specific knowledge of Motoko is needed to follow along. There is also a [Rust](https://github.com/dfinity/examples/tree/master/rust/threshold-ecdsa) version available in the same repo and follows the same commands for deploying. -::: - -## Prerequisites -- [x] Download and [install the IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/index.md) if you do not already have it. -- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` +> [!TIP] +> This walkthrough focuses on the version of the sample canister code written in [Motoko](https://internetcomputer.org/docs/current/developer-docs/backend/motoko/index.md) programming language, but no specific knowledge of Motoko is needed to follow along. There is also a [Rust](https://github.com/dfinity/examples/tree/master/rust/threshold-ecdsa) version available in the same repo and follows the same commands for deploying. ## Getting started Sample code for `threshold-ecdsa` is provided in the [examples repository](https://github.com/dfinity/examples), under either [`/motoko`](https://github.com/dfinity/examples/tree/master/motoko/threshold-ecdsa) or [`/rust`](https://github.com/dfinity/examples/tree/master/rust/threshold-ecdsa) sub-directories. It requires at least [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/index.md) version 0.11.0 for local development. -## Deploy and test the canister locally +### Prerequisites +This example requires an installation of: -This tutorial will use the Motoko version of the canister: +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` + +Begin by opening a terminal window. + +## Step 1: Setup the project environment + +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: ```bash cd examples/motoko/threshold-ecdsa dfx start --background -npm install -dfx deploy ``` -#### What this does -- `dfx start --background` starts a local instance of the IC via the IC SDK -- `dfx deploy` deploys the code in the user's directory as a canister on the local version of the IC +## Step 2: Deploy the canisters + +```bash +dfx deploy +``` If successful, you should see something like this: @@ -58,19 +53,18 @@ URLs: If you open the URL in a web browser, you will see a web UI that shows the public methods the canister exposes. Since the canister exposes `public_key` and `sign` methods, those are rendered in the web UI. - -### Deploying the canister on the mainnet +## Deploying the canister on the mainnet To deploy this canister to the mainnet, one needs to do two things: - Acquire cycles (the equivalent of "gas" on other blockchains). This is necessary for all canisters. - Update the sample source code to have the right key ID. This is unique to this canister. -#### Acquire cycles to deploy +### Acquire cycles to deploy Deploying to the Internet Computer requires [cycles](https://internetcomputer.org/docs/current/developer-docs/getting-started/tokens-and-cycles) (the equivalent of "gas" on other blockchains). -#### Update source code with the right key ID +### Update source code with the right key ID To deploy the sample code, the canister needs the right key ID for the right environment. Specifically, one needs to replace the value of the `key_id` in the `src/ecdsa_example_motoko/main.mo` file of the sample code. Before deploying to the mainnet, one should modify the code to use the right name of the `key_id`. @@ -102,11 +96,10 @@ let { signature } = await ic.sign_with_ecdsa({ }); ``` -:::caution -To deploy to IC mainnet, one needs to replace the value in `key_id` fields with the values `"dfx_test_key"` to instead have either `"test_key_1"` or `"key_1"` depending on the desired intent. -::: +> [!WARNING] +> To deploy to IC mainnet, one needs to replace the value in `key_id` fields with the values `"dfx_test_key"` to instead have either `"test_key_1"` or `"key_1"` depending on the desired intent. -### Deploy to the mainnet via IC SDK +### Deploying To [deploy via mainnet](https://internetcomputer.org/docs/current/developer-docs/setup/deploy-mainnet.md), run the following commands: @@ -127,7 +120,7 @@ In the example above, `ecdsa_example_motoko` has the URL https://a3gq9-oaaaa-aaa ## Obtaining public keys -### Using the Candid Web UI +### Using the Candid UI If you deployed your canister locally or to the mainnet, you should have a URL to the Candid web UI where you can access the public methods. We can call the `public-key` method. diff --git a/motoko/threshold-schnorr/README.md b/motoko/threshold-schnorr/README.md index 199eb7672..f4ae0c23b 100644 --- a/motoko/threshold-schnorr/README.md +++ b/motoko/threshold-schnorr/README.md @@ -1,13 +1,5 @@ ---- -keywords: [advanced, motoko, threshold schnorr, schnorr, signature] ---- - # Threshold Schnorr -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/threshold-schnorr) - -## Overview - We present a minimal example canister smart contract for showcasing the [threshold Schnorr](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-sign_with_schnorr) @@ -33,23 +25,22 @@ Motoko programming language. There is also a [Rust](https://github.com/dfinity/examples/tree/master/rust/threshold-schnorr) version available in the same repo and follows the same commands for deploying. - -## Prerequisites -- [x] Download and [install the IC - SDK](https://internetcomputer.org/docs/current/developer-docs/setup/index.md) - if you do not already have it. For local testing, `dfx >= 0.22.0-beta.0` is - required. -- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` - ## Getting started Sample code for `threshold-schnorr-example` is provided in the [examples repository](https://github.com/dfinity/examples), under either [`/motoko`](https://github.com/dfinity/examples/tree/master/motoko/threshold-schnorr) or [`/rust`](https://github.com/dfinity/examples/tree/master/rust/threshold-schnorr) sub-directories. -### Deploy and test the canister locally +### Prerequisites +This example requires an installation of: -This tutorial will use the Motoko version of the canister. +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` + +Begin by opening a terminal window. + +## Step 1: Setup the project environment + +Navigate into the folder containing the project's files, start a local instance of the Internet Computer and deploy the project with the commands: -To deploy: ```bash cd examples/motoko/threshold-schnorr dfx start --background @@ -83,18 +74,18 @@ If you open the URL in a web browser, you will see a web UI that shows the public methods the canister exposes. Since the canister exposes `public_key` and `sign`, those are rendered in the web UI. -### Deploying the canister on the mainnet +## Deploying the canister on the mainnet To deploy this canister the mainnet, one needs to do two things: - Acquire cycles (equivalent of "gas" in other blockchains). This is necessary for all canisters. - Update the sample source code to have the right key ID. This is unique to this canister. -#### Acquire cycles to deploy +### Acquire cycles to deploy Deploying to the Internet Computer requires [cycles](https://internetcomputer.org/docs/current/developer-docs/getting-started/tokens-and-cycles) (the equivalent of "gas" on other blockchains). -#### Update source code with the right key ID +### Update source code with the right key ID To deploy the sample code, the canister needs the right key ID for the right environment. Specifically, one needs to replace the value of the `key_id` in the `src/schnorr_example_motoko/src/lib.rs` file of the sample code. Before deploying to mainnet, one should modify the code to use the right name of the `key_id`. @@ -115,7 +106,8 @@ IMPORTANT: To deploy to IC mainnet, one needs to replace `"dfx_test_key"` with either "test_key_1"` or `"key_1"` depending on the desired intent. Both uses of key ID in `src/schnorr_example_motoko/src/main.mo` must be consistent. -#### Deploy to the mainnet via IC SDK + +### Deploying To [deploy via the mainnet](https://internetcomputer.org/docs/current/developer-docs/setup/deploy-mainnet.md), run the following commands: @@ -139,7 +131,7 @@ mainnet. ## Obtaining public keys -### Using the Candid Web UI +### Using the Candid UI If you deployed your canister locally or to the mainnet, you should have a URL to the Candid web UI where you can access the public methods. We can call the `public-key` method. diff --git a/motoko/token_transfer/README.md b/motoko/token_transfer/README.md index 5607baba9..95ad249d8 100644 --- a/motoko/token_transfer/README.md +++ b/motoko/token_transfer/README.md @@ -1,9 +1,5 @@ # Token transfer -[View this samples code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/token_transfer). - -## Overview - Token transfer is a canister that can transfer ICRC-1 tokens from its account to other accounts. It is an example of a canister that uses an ICRC-1 ledger canister. Sample code is available in [Motoko](https://github.com/dfinity/examples/tree/master/motoko/token_transfer) and [Rust](https://github.com/dfinity/examples/tree/master/rust/token_transfer). ## Architecture @@ -12,54 +8,44 @@ The sample code revolves around one core transfer function which takes as input This sample will use the Motoko variant. -## Prerequisites - +### Prerequisites This example requires an installation of: -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). -- [x] Download and install [git](https://git-scm.com/downloads). - -## How to get there - -The following steps will guide you through the process of setting up the token transfer canister for your own project. +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). -:::info +Begin by opening a terminal window. -If you just want to interact with this example, follow steps 4-8 and 10-12 below. +## Step 1: Setup the project environment -::: - -### Step 1: Create a new `dfx` project and navigate into the project's directory. +Start a local instance of the Internet Computer and create a new project with the commands: ```bash +dfx start --background dfx new --type=motoko token_transfer --no-frontend cd token_transfer ``` -### Step 2: Determine ICRC-1 ledger file locations - -:::info +## Step 2: Determine ICRC-1 ledger file locations -[Learn more about how to setup the ICRC-1 ledger locally](https://internetcomputer.org/docs/current/developer-docs/defi/icrc-1/icrc1-ledger-setup). +> [!TIP] +> [Learn more about how to setup the ICRC-1 ledger locally](https://internetcomputer.org/docs/current/developer-docs/defi/icrc-1/icrc1-ledger-setup) -::: +Go to the [releases overview](https://dashboard.internetcomputer.org/releases) and copy the latest replica binary revision. -Go to the [releases overview](https://dashboard.internetcomputer.org/releases) and copy the latest replica binary revision. At the time of writing, this is `d87954601e4b22972899e9957e800406a0a6b929`. +The URL for the ledger Wasm module is `https://download.dfinity.systems/ic//canisters/ic-icrc1-ledger.wasm.gz`. -The URL for the ledger Wasm module is `https://download.dfinity.systems/ic//canisters/ic-icrc1-ledger.wasm.gz`, so with the above revision it would be `https://download.dfinity.systems/ic/d87954601e4b22972899e9957e800406a0a6b929/canisters/ic-icrc1-ledger.wasm.gz`. - -The URL for the ledger .did file is `https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icrc1/ledger/ledger.did`, so with the above revision it would be `https://raw.githubusercontent.com/dfinity/ic/d87954601e4b22972899e9957e800406a0a6b929/rs/rosetta-api/icrc1/ledger/ledger.did`. +The URL for the ledger .did file is `https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icrc1/ledger/ledger.did`. **OPTIONAL:** If you want to make sure, you have the latest ICRC-1 ledger files you can run the following script. ```sh -curl -o download_latest_icrc1_ledger.sh "https://raw.githubusercontent.com/dfinity/ic/326df23607fc8280a047daba2d8462f1dfc57466/rs/rosetta-api/scripts/download_latest_icrc1_ledger.sh" +curl -o download_latest_icrc1_ledger.sh "https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/scripts/download_latest_icrc1_ledger.sh" chmod +x download_latest_icrc1_ledger.sh ./download_latest_icrc1_ledger.sh ``` -### Step 3: Configure the `dfx.json` file to use the ledger : +## Step 3: Configure the `dfx.json` file to use the ledger Replace its contents with this but adapt the URLs to be the ones you determined in step 2: @@ -73,8 +59,8 @@ Replace its contents with this but adapt the URLs to be the ones you determined }, "icrc1_ledger_canister": { "type": "custom", - "candid": "https://raw.githubusercontent.com/dfinity/ic/d87954601e4b22972899e9957e800406a0a6b929/rs/rosetta-api/icrc1/ledger/ledger.did", - "wasm": "https://download.dfinity.systems/ic/d87954601e4b22972899e9957e800406a0a6b929/canisters/ic-icrc1-ledger.wasm.gz" + "candid": "https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icrc1/ledger/ledger.did", + "wasm": "https://download.dfinity.systems/ic//canisters/ic-icrc1-ledger.wasm.gz" } }, "defaults": { @@ -97,31 +83,23 @@ If you chose to download the ICRC-1 ledger files with the script, you need to re ... ``` -### Step 4: Start a local replica: - -```bash -dfx start --background --clean -``` - -### Step 5: Use the anonymous identity as the minting account: +## Step 4: Use the anonymous identity as the minting account ```bash export MINTER=$(dfx --identity anonymous identity get-principal) ``` -:::info - -Transfers from the minting account will create Mint transactions. Transfers to the minting account will create Burn transactions. +> [!TIP] +> Transfers from the minting account will create Mint transactions. Transfers to the minting account will create Burn transactions. -::: -### Step 6: Record your default identity's principal to mint an initial balance to when deploying the ledger: +## Step 5: Record your default identity's principal to mint an initial balance to when deploying the ledger ```bash export DEFAULT=$(dfx identity get-principal) ``` -### Step 7: Deploy the ICRC-1 ledger locally: +## Step 6: Deploy the ICRC-1 ledger locally Take a moment to read the details of the call made below. Not only are you deploying an ICRC-1 ledger canister, you are also: @@ -157,13 +135,10 @@ URLs: icrc1_ledger_canister: http://127.0.0.1:4943/?canisterId=bnz7o-iuaaa-aaaaa-qaaaa-cai&id=mxzaz-hqaaa-aaaar-qaada-cai ``` -### Step 8: Verify that the ledger canister is healthy and working as expected by using the command: +## Step 7: Verify that the ledger canister is healthy and working as expected by using the command -:::info - -[Learn more about how to interact with the ICRC-1 ledger](https://internetcomputer.org/docs/current/developer-docs/defi/icrc-1/using-icrc1-ledger#icrc-1-and-icrc-1-extension-endpoints). - -::: +> ![TIP] +> [Learn more about how to interact with the ICRC-1 ledger](https://internetcomputer.org/docs/current/developer-docs/defi/icrc-1/using-icrc1-ledger#icrc-1-and-icrc-1-extension-endpoints). ````bash dfx canister call icrc1_ledger_canister icrc1_balance_of "(record { @@ -178,7 +153,7 @@ The output should be: (10_000_000_000 : nat) ```` -### Step 9: Prepare the token transfer canister: +## Step 8: Prepare the token transfer canister Replace the contents of the `src/token_transfer_backend/main.mo` file with the following: @@ -238,19 +213,16 @@ actor { ``` -### Step 10: Deploy the token transfer canister: +## Step 9: Deploy the token transfer canister ```bash dfx deploy token_transfer_backend ``` -### Step 11: Transfer funds to your canister: - -:::info - -Make sure that you are using the default `dfx` account that we minted tokens to in step 7 for the following steps. +## Step 10: Transfer funds to your canister -::: +> [!TIP] +> Make sure that you are using the default `dfx` account that we minted tokens to in step 7 for the following steps. Make the following call to transfer 10 tokens to the canister: @@ -269,7 +241,7 @@ If successful, the output should be: (variant { Ok = 1 : nat }) ``` -### Step 12: Transfer funds from the canister: +## Step 11: Transfer funds from the canister Now that the canister owns tokens on the ledger, you can transfer 1 token from the canister to another account, in this case back to the default account: diff --git a/motoko/token_transfer_from/README.md b/motoko/token_transfer_from/README.md index adde72c79..0bc1270f4 100644 --- a/motoko/token_transfer_from/README.md +++ b/motoko/token_transfer_from/README.md @@ -1,9 +1,5 @@ # Token transfer_from -[View this samples code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/token_transfer_from). - -## Overview - `token_transfer_from_backend` is a canister that can transfer ICRC-1 tokens on behalf of accounts to other accounts. It is an example of a canister that uses an ICRC-1 ledger canister that supports the [ICRC-2](https://github.com/dfinity/ICRC-1/tree/main/standards/ICRC-2) approve and transfer from standard. Sample code is available in [Motoko](https://github.com/dfinity/examples/tree/master/motoko/token_transfer_from) and [Rust](https://github.com/dfinity/examples/tree/master/rust/token_transfer_from). ## Architecture @@ -12,76 +8,59 @@ The sample code revolves around one core transfer function which takes as input This sample will use the Rust variant. -## Prerequisites - +### Prerequisites This example requires an installation of: -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). -- [x] Download and install [git.](https://git-scm.com/downloads) +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). -## How to get there +Begin by opening a terminal window. -The following steps will guide you through the process of setting up the token transfer canister for your own project. - -:::info +## Step 1: Setup the project environment -If you just want to interact with this example, follow steps 4-6 and 8-10 below. - -::: - -### Step 1: Create a new `dfx` project and navigate into the project's directory. +Start a local instance of the Internet Computer and create a new project with the commands: ```bash -dfx new --type=motoko token_transfer_from --no-frontend -cd token_transfer_from +dfx start --background +dfx new --type=motoko token_transfer --no-frontend +cd token_transfer ``` -### Step 2: Determine ICRC-1 ledger file locations +## Step 2: Determine ICRC-1 ledger file locations -:::info +> [!TIP] +> [Learn more about how to setup the ICRC-1 ledger locally](https://internetcomputer.org/docs/current/developer-docs/defi/icrc-1/icrc1-ledger-setup) -You can read more about how to setup the ICRC-1 ledger locally [here](https://internetcomputer.org/docs/current/developer-docs/defi/icrc-1/icrc1-ledger-setup). +Go to the [releases overview](https://dashboard.internetcomputer.org/releases) and copy the latest replica binary revision. -::: - -Go to the [releases overview](https://dashboard.internetcomputer.org/releases) and copy the latest replica binary revision. At the time of writing, this is `d87954601e4b22972899e9957e800406a0a6b929`. +The URL for the ledger Wasm module is `https://download.dfinity.systems/ic//canisters/ic-icrc1-ledger.wasm.gz`. -The URL for the ledger Wasm module is `https://download.dfinity.systems/ic//canisters/ic-icrc1-ledger.wasm.gz`, so with the above revision it would be `https://download.dfinity.systems/ic/d87954601e4b22972899e9957e800406a0a6b929/canisters/ic-icrc1-ledger.wasm.gz`. - -The URL for the ledger .did file is `https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icrc1/ledger/ledger.did`, so with the above revision it would be `https://raw.githubusercontent.com/dfinity/ic/d87954601e4b22972899e9957e800406a0a6b929/rs/rosetta-api/icrc1/ledger/ledger.did`. +The URL for the ledger .did file is `https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icrc1/ledger/ledger.did`. **OPTIONAL:** If you want to make sure, you have the latest ICRC-1 ledger files you can run the following script. ```sh -curl -o download_latest_icrc1_ledger.sh "https://raw.githubusercontent.com/dfinity/ic/326df23607fc8280a047daba2d8462f1dfc57466/rs/rosetta-api/scripts/download_latest_icrc1_ledger.sh" +curl -o download_latest_icrc1_ledger.sh "https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/scripts/download_latest_icrc1_ledger.sh" chmod +x download_latest_icrc1_ledger.sh ./download_latest_icrc1_ledger.sh ``` -### Step 3: Configure the `dfx.json` file to use the ledger : - -Replace its contents with this but adapt the URLs to be the ones you determined in step 2. Note that we are deploying the ICRC-1 ledger to the same canister id the ckBTC ledger uses on mainnet. This will make it easier to interact with it later. +## Step 3: Configure the `dfx.json` file to use the ledger -:::info - -Don't forget to add the `icrc1_ledger_canister` as a dependency for `token_transfer_from_backend`, otherwise the build will fail. - -::: +Replace its contents with this but adapt the URLs to be the ones you determined in step 2: ```json { "canisters": { - "token_transfer_from_backend": { - "main": "src/token_transfer_from_backend/main.mo", + "token_transfer_backend": { + "main": "src/token_transfer_backend/main.mo", "type": "motoko", "dependencies": ["icrc1_ledger_canister"] }, "icrc1_ledger_canister": { "type": "custom", - "candid": "https://raw.githubusercontent.com/dfinity/ic/d87954601e4b22972899e9957e800406a0a6b929/rs/rosetta-api/icrc1/ledger/ledger.did", - "wasm": "https://download.dfinity.systems/ic/d87954601e4b22972899e9957e800406a0a6b929/canisters/ic-icrc1-ledger.wasm.gz", - "specified_id": "mxzaz-hqaaa-aaaar-qaada-cai" + "candid": "https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icrc1/ledger/ledger.did", + "wasm": "https://download.dfinity.systems/ic//canisters/ic-icrc1-ledger.wasm.gz" } }, "defaults": { @@ -97,26 +76,31 @@ Don't forget to add the `icrc1_ledger_canister` as a dependency for `token_trans If you chose to download the ICRC-1 ledger files with the script, you need to replace the Candid and Wasm file entries: -``` +```json ... "candid": icrc1_ledger.did, "wasm" : icrc1_ledger.wasm.gz, -... + ... ``` -### Step 4: Start a local replica: +## Step 4: Use the anonymous identity as the minting account ```bash -dfx start --background --clean +export MINTER=$(dfx --identity anonymous identity get-principal) ``` -### Step 5: Deploy the ICRC-1 ledger locally: +> [!TIP] +> Transfers from the minting account will create Mint transactions. Transfers to the minting account will create Burn transactions. -:::info -Transfers from the `minting_account` will create Mint transactions. Transfers to the minting account will create Burn transactions. +## Step 5: Record your default identity's principal to mint an initial balance to when deploying the ledger + +```bash +export DEFAULT=$(dfx identity get-principal) +``` + +## Step 6: Deploy the ICRC-1 ledger locally -::: Take a moment to read the details of the call made below. Not only are you deploying an ICRC-1 ledger canister, you are also: @@ -165,18 +149,16 @@ URLs: icrc1_ledger_canister: http://127.0.0.1:4943/?canisterId=bnz7o-iuaaa-aaaaa-qaaaa-cai&id=mxzaz-hqaaa-aaaar-qaada-cai ``` -### Step 6: Verify that the ledger canister is healthy and working as expected by using the command: - -:::info - -[Learn more about how to interact with the ICRC-1 ledger](https://internetcomputer.org/docs/current/developer-docs/defi/icrc-1/using-icrc1-ledger#icrc-1-and-icrc-1-extension-endpoints). +## Step 7: Verify that the ledger canister is healthy and working as expected by using the command -::: +> ![TIP] +> [Learn more about how to interact with the ICRC-1 ledger](https://internetcomputer.org/docs/current/developer-docs/defi/icrc-1/using-icrc1-ledger#icrc-1-and-icrc-1-extension-endpoints). ````bash dfx canister call icrc1_ledger_canister icrc1_balance_of "(record { - owner = principal \"$(dfx identity --identity default get-principal)\"; -})" + owner = principal \"${DEFAULT}\"; + } +)" ``` The output should be: @@ -185,7 +167,7 @@ The output should be: (10_000_000_000 : nat) ```` -### Step 7: Prepare the token transfer canister: +## Step 8: Prepare the token transfer canister Replace the contents of the `src/token_transfer_from_backend/main.mo` file with the following: @@ -234,7 +216,7 @@ actor { // initiate the transfer let transferFromResult = await Icrc1Ledger.icrc2_transfer_from(transferFromArgs); - // check if the transfer was successfull + // check if the transfer was successful switch (transferFromResult) { case (#Err(transferError)) { return #err("Couldn't transfer funds:\n" # debug_show (transferError)); @@ -250,13 +232,13 @@ actor { ``` -### Step 8: Deploy the token transfer canister: +## Step 9: Deploy the token transfer canister ```bash dfx deploy token_transfer_from_backend ``` -### Step 9: Approve the canister to transfer funds on behalf of the user: +## Step 10: Approve the canister to transfer funds on behalf of the user :::info @@ -283,7 +265,7 @@ If successful, the output should be: (variant { Ok = 1 : nat }) ``` -### Step 10: Let the canister transfer funds on behalf of the user: +## Step 11: Let the canister transfer funds on behalf of the user Now that the canister has an approval for the `default` identities tokens on the ledger, the canister can transfer 1 token on behalf of the `default` identity to another account, in this case to the canisters own account. diff --git a/motoko/vetkd/README.md b/motoko/vetkd/README.md index a5a3de0ee..a7c5a5be1 100644 --- a/motoko/vetkd/README.md +++ b/motoko/vetkd/README.md @@ -1,11 +1,5 @@ ---- -keywords: [advanced, motoko, vetkd, vetkeys] ---- - # vetKD API -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/vetkd) - This repository provides a canister (`src/system_api`) that offers the vetKD system API proposed in https://github.com/dfinity/interface-spec/pull/158, implemented in an **unsafe** manner **for demonstration purposes**. Additionally, the repository provides: @@ -21,38 +15,33 @@ Additionally, the repository provides: The implementation of [the proposed vetKD system API](https://github.com/dfinity/interface-spec/pull/158) used in this example is **unsafe**, e.g., we hard-code a master secret key, rather than using a master secret key that is distributed among sufficiently many Internet Computer nodes through distributed key generation. **Do not use this in production or for sensitive data**! This example is solely provided **for demonstration purposes** to collect feedback on the mentioned vetKD system API. See also the respective disclaimer [in the system API canister implementation](https://github.com/dfinity/examples/blob/master/rust/vetkd/src/system_api/src/lib.rs#L19-L26). -## Prerequisites -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/). -- [x] Install [Node.js](https://nodejs.org/en/download/). +### Prerequisites +This example requires an installation of: + +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). - [x] Install [Rust](https://www.rust-lang.org/tools/install), and add Wasm as a target (`rustup target add wasm32-unknown-unknown`). Note that Rust is only needed for compiling the (insecure) canister offering the vetKD system API, which later would be directly integrated into ICP. - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -## Running locally +Begin by opening a terminal window. -- #### Step 1: Start a local replica: +## Step 1: Setup the project environment -```sh -dfx start -``` +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: -- #### Step 2: Open a new terminal window. +```bash +cd examples/motoko/vetkd +dfx start --background +``` -- #### Step 3: Ensure `dfx` uses the canister IDs that are hard-coded in the Rust source code: +## Step 2: Ensure `dfx` uses the canister IDs that are hard-coded in the Rust source code: -```sh -cd examples/motoko/vetkd +```bash dfx canister create system_api --specified-id s55qq-oqaaa-aaaaa-aaakq-cai ``` Without this, `dfx` may use different canister IDs for the `system_api` and `app_backend` canisters in your local environment. -- #### Step 4: Ensure that the required node modules are available in your project directory, if needed, by running the following command: - -```sh -npm install -``` - -- #### Step 5: Register, build, and deploy the project: +## Step 3: Register, build, and deploy the project: ```sh dfx deploy @@ -71,4 +60,4 @@ Backend canister via Candid interface: system_api: http://127.0.0.1:4943/?canisterId=avqkn-guaaa-aaaaa-qaaea-cai&id=s55qq-oqaaa-aaaaa-aaakq-cai ``` -- #### Step 6: Open the printed URL for the `app_frontend_js` in your browser. +## Step 4: Open the printed URL for the `app_frontend_js` in your browser. diff --git a/motoko/whoami/README.md b/motoko/whoami/README.md index 23248ea03..1824097ff 100644 --- a/motoko/whoami/README.md +++ b/motoko/whoami/README.md @@ -1,17 +1,8 @@ ---- -keywords: [beginner, motoko, who am i, whoami] ---- - # Who am I? -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/whoami) - -## Overview - This example demonstrates how a canister can identify its caller and itself. -## Prerequisites - +### Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). @@ -19,14 +10,16 @@ This example requires an installation of: Begin by opening a terminal window. -### Step 1: Navigate into the folder containing the project's files and start a local instance of the replica with the command: +## Step 1: Setup the project environment + +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: ```bash cd examples/motoko/whoami dfx start --background ``` -### Step 2: Build and deploy the canister: +## Step 2: Build and deploy the canister ```bash dfx canister install whoami --argument='(principal "2mxjj-pyyts-rk2hl-2xyka-avylz-dfama-pqui5-pwrhx-wtq2x-xl5lj-qqe")' @@ -34,21 +27,21 @@ dfx build dfx deploy ``` -### Step 3: Invoke the `whoami` method: +## Step 3: Invoke the `whoami` method ```bash dfx canister call whoami whoami ``` -### Step 4: Observe your principal identifier. +## Step 4: Observe your principal identifier -### Step 5: Invoke the `id` method: +## Step 5: Invoke the `id` method ```bash dfx canister call whoami id ``` -### Step 6: Observe the principal identifier of your canister. +## Step 6: Observe the principal identifier of your canister ## Security considerations and best practices From 80ea5501da7ba781233bf19f806d648baf0f59a7 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon Date: Wed, 18 Dec 2024 16:52:35 -0600 Subject: [PATCH 03/51] update rust readmes --- motoko/canister_logs/README.md | 54 +++++----- rust/basic_bitcoin/README.md | 15 +-- rust/basic_dao/README.md | 42 ++++---- rust/basic_ethereum/README.md | 12 +-- rust/canister-info/README.md | 6 -- rust/canister-snapshots/README.md | 42 +++----- rust/canister_logs/README.md | 155 +++++++++++++--------------- rust/composite_query/README.md | 17 +-- rust/counter/README.md | 23 ++--- rust/defi/README.md | 35 +++---- rust/dip721-nft-container/README.md | 33 +++--- rust/face-recognition/README.md | 47 ++++----- rust/guards/README.md | 30 +++--- rust/hello/README.md | 49 +++------ rust/icp_transfer/README.md | 79 +++++--------- rust/image-classification/README.md | 47 +++------ rust/nft-wallet/README.md | 22 ++-- rust/parallel_calls/README.md | 29 ++---- rust/performance_counters/README.md | 37 +++---- rust/periodic_tasks/README.md | 8 -- 20 files changed, 301 insertions(+), 481 deletions(-) diff --git a/motoko/canister_logs/README.md b/motoko/canister_logs/README.md index ad69e31b5..545dd99b9 100644 --- a/motoko/canister_logs/README.md +++ b/motoko/canister_logs/README.md @@ -1,66 +1,64 @@ ---- -keywords: [beginner, motoko, canister logs, logging] ---- - # Canister logs -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/canister_logs) - ## Prerequisites -This example requires an installation of: -- [x] DFX version 0.19.0 or newer -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/). -- [x] Download the following project files from GitHub: `git clone https://github.com/dfinity/examples/` +- [x] Install the [IC + SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -You will need to have 3 terminal windows: -- Terminal A: Running a DFX instance and separating its output from anything else -- Terminal B: Deploying a canister and seeing its output -- Terminal C: Reading logs interactively +## Step 1: Setup project environment + +Navigate into the folder containing the project's files and start a local instance of the replica with the command: -### Step 1: Navigate into the folder containing the project's files and start a local instance of the replica with the command: +```shell +dfx start --clean +``` + +You will need to have 3 terminal windows: +- Terminal A: Running a `dfx` instance and separating its output from anything else. +- Terminal B: Deploying a canister and seeing its output. +- Terminal C: Reading logs interactively. ```shell # Terminal A -- for running DFX and separating its output from anything else. -$ cd examples/motoko/canister_logs -$ dfx start --clean +cd examples/motoko/canister_logs # Terminal B -- for deploying the canister and calling its methods. -$ cd examples/motoko/canister_logs +cd examples/motoko/canister_logs # Terminal C -- for polling logs. -$ cd examples/motoko/canister_logs +cd examples/motoko/canister_logs ``` -### Step 2: Deploy the canister: +## Step 2: Deploy the canister ```shell # Terminal B -$ dfx deploy +dfx deploy ``` -### Step 3: Check canister logs: +## Step 3: Check canister logs Expect to see logs from timer traps. ```shell # Terminal B -$ dfx canister logs CanisterLogs +dfx canister logs CanisterLogs [0. 2024-05-23T08:32:26.203980235Z]: right before timer trap [1. 2024-05-23T08:32:26.203980235Z]: [TRAP]: timer trap [2. 2024-05-23T08:32:31.836721763Z]: right before timer trap [3. 2024-05-23T08:32:31.836721763Z]: [TRAP]: timer trap ``` -### Step 4: Call `print` method and check the logs: +## Step 4: Call `print` method and check the logs ```shell # Terminal B -$ dfx canister call CanisterLogs print hi +dfx canister call CanisterLogs print hi () # Expect to see new log entry. -$ dfx canister logs CanisterLogs +dfx canister logs CanisterLogs ... [8. 2024-05-23T08:32:46.598972616Z]: right before timer trap [9. 2024-05-23T08:32:46.598972616Z]: [TRAP]: timer trap @@ -70,7 +68,7 @@ $ dfx canister logs CanisterLogs ... ``` -### Step 5: Start constantly polling logs: +## Step 5: Start constantly polling logs In order not to call `dfx canister logs CanisterLogs` after every canister call in a separate terminal window/pane C start a script that will constantly poll logs: @@ -86,7 +84,7 @@ $ ./poll_logs.sh ... ``` -### Step 6: Call `print`, `trap` and other canister methods: +## Step 6: Call `print`, `trap` and other canister methods ```shell # Terminal B diff --git a/rust/basic_bitcoin/README.md b/rust/basic_bitcoin/README.md index f43a1f5e7..6341aa5ea 100644 --- a/rust/basic_bitcoin/README.md +++ b/rust/basic_bitcoin/README.md @@ -1,12 +1,5 @@ ---- -keywords: [advanced, rust, bitcoin, btc, integration, bitcoin integration] ---- - # Basic Bitcoin -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/basic_bitcoin) - -## Overview This tutorial will walk you through how to deploy a sample [canister smart contract](https://internetcomputer.org/docs/current/developer-docs/multi-chain/bitcoin/overview) **that can send and receive Bitcoin** on the Internet Computer. ## Architecture @@ -21,18 +14,16 @@ of the Internet Computer. For a deeper understanding of the ICP < > BTC integration, see the [Bitcoin integration documentation](https://wiki.internetcomputer.org/wiki/Bitcoin_Integration). -## Prerequisites +### Prerequisites * [x] Install the [IC - SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). + SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0-beta.0` is required. * [x] On macOS, `llvm` with the `wasm32-unknown-unknown` target (which is not included in the XCode installation by default) is required. To install, run `brew install llvm`. ## Step 1: Building and deploying sample code -### Clone the smart contract - This tutorial has the same smart contract written in [Motoko](https://internetcomputer.org/docs/current/developer-docs/backend/motoko/index.md) using ECDSA, Schnorr, and Bitcoin API. @@ -130,7 +121,7 @@ from three types of addresses: Note that P2TR *key path* spending with a tweaked key is currently not available on the IC because the threshold Schnorr signing interface does not allow applying BIP341 tweaks to the private key. In contrast, the -tweaked public key is used to spend in the script path, which is availble on the +tweaked public key is used to spend in the script path, which is available on the IC. For a technical comparison of different ways of how single-signer P2TR addresses can be constructed and used, you may want to take a look at [this post](https://bitcoin.stackexchange.com/a/111100) by Pieter Wuille. diff --git a/rust/basic_dao/README.md b/rust/basic_dao/README.md index c508230b9..21a8e403b 100644 --- a/rust/basic_dao/README.md +++ b/rust/basic_dao/README.md @@ -1,15 +1,7 @@ ---- -keywords: [advanced, rust, dao, decentralized organization, decentralized org] ---- - # Basic DAO -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/basic_dao) - This sample project demonstrates a basic [decentralized autonomous organization](https://en.wikipedia.org/wiki/Decentralized_autonomous_organization) (DAO) that can be deployed to the [Internet Computer](https://github.com/dfinity/ic). The basic DAO sample code is available in [Motoko](https://github.com/dfinity/examples/tree/master/motoko/basic_dao) and [Rust](https://github.com/dfinity/examples/tree/master/rust/basic_dao). You can see a quick introduction on [YouTube](https://youtu.be/3IcYlieA-EE). -## Overview - A `basic_dao` can be initialized with a set of accounts: mappings from principal IDs to a number of tokens. Account owners can query their account balance by calling `account_balance` and transfer tokens to other accounts by calling `transfer`. Anyone can call `list_accounts` to view all accounts. Account owners can submit proposals by calling `submit_proposal`. A proposal specifies a canister, method, and arguments for this method. Account owners can cast votes (either `Yes` or `No`) on a proposal by calling `vote`. The amount of votes cast is equal to the amount of tokens the account owner has. If enough `Yes` votes are cast, `basic_dao` will execute the proposal by calling the proposal’s given method with the given args against the given canister. If enough `No` votes are cast, the proposal is not executed, and is instead marked as `Rejected`. @@ -18,37 +10,39 @@ Certain system parameters, like the number of `Yes` votes needed to pass a propo View the [canister service definition](https://github.com/dfinity/examples/blob/master/rust/basic_dao/src/basic_dao/src/basic_dao.did) for more details. -## Prerequisites +### Prerequisites This example requires an installation of: - [x] The Rust toolchain (e.g. cargo). - [x] [didc.](https://github.com/dfinity/candid/tree/master/tools/didc) -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/). +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` Begin by opening a terminal window. -### Step 1: Build the `basic_dao` canister: +## Step 1: Build the `basic_dao` canister ```bash make clean; make ``` -### Step 2: Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the command: +## Step 2: Setup the dev environment + +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the command: ```bash cd basic_dao dfx start --background ``` -### Step 3: Create test identities with the commands: +## Step 3: Create test identities with the commands ```bash dfx identity new --disable-encryption Alice; dfx identity use Alice; export ALICE=$(dfx identity get-principal); dfx identity new --disable-encryption Bob; dfx identity use Bob; export BOB=$(dfx identity get-principal); ``` -### Step 4: Deploy basic_dao with the initial test accounts: +## Step 4: Deploy basic_dao with the initial test accounts ```bash dfx deploy --argument "(record { @@ -63,7 +57,7 @@ dfx deploy --argument "(record { })" ``` -### Step 5: List accounts and confirm you see the two test accounts: +## Step 5: List accounts and confirm you see the two test accounts ```bash dfx canister call basic_dao list_accounts '()' @@ -86,7 +80,7 @@ Output: ) ``` -### Step 6: Call `account_balance` as Bob: +## Step 6: Call `account_balance` as Bob ```bash dfx canister call basic_dao account_balance '()' @@ -98,7 +92,7 @@ You should see the output: (record { amount_e8s = 100_000_000 : nat64 }) ``` -### Step 7: Transfer tokens to Alice: +## Step 7: Transfer tokens to Alice ```bash dfx canister call basic_dao transfer "(record { to = principal \"$ALICE\"; amount = record { amount_e8s = 90_000_000:nat;};})"; @@ -110,7 +104,7 @@ Output: (variant { Ok }) ``` -### Step 8: List accounts and see that the transfer was made: +## Step 8: List accounts and see that the transfer was made ```bash dfx canister call basic_dao list_accounts '()' @@ -137,7 +131,9 @@ Output: Note that the transfer fee was deducted from Bob's account. ::: -### Step 9: Let's make a proposal to change the transfer fee. You can call `get_system_params` to learn the current transfer fee: +## Step 9: Let's make a proposal to change the transfer fee + +You can call `get_system_params` to learn the current transfer fee: ```bash dfx canister call basic_dao get_system_params '()'; @@ -177,7 +173,7 @@ Output: blob "DIDL\03l\01\f2\c7\94\ae\03\01n\02l\01\b9\ef\93\80\08x\01\00\01 N\00\00\00\00\00\00" ``` -### Step 10: We can then submit the proposal: +## Step 10: We can then submit the proposal ```bash dfx canister call basic_dao submit_proposal '(record { canister_id = principal "rrkah-fqaaa-aaaaa-aaaaq-cai"; @@ -191,7 +187,7 @@ Note the output proposal ID: (variant { Ok = 0 : nat64 }) ``` -### Step 11: Confirm the proposal was created: +## Step 11: Confirm the proposal was created ```bash dfx canister call basic_dao get_proposal '(0:nat64)' @@ -199,7 +195,7 @@ dfx canister call basic_dao get_proposal '(0:nat64)' You should see `state = variant { Open };` in the output. -### Step 12: Vote on the proposal: +## Step 12: Vote on the proposal ```bash dfx canister call basic_dao vote '(record { proposal_id = 0:nat64; vote = variant { Yes };})' @@ -253,7 +249,7 @@ Output: ) ``` -### Resources +## Resources - [ic-cdk](https://docs.rs/ic-cdk/latest/ic_cdk/) - [ic-cdk-macros](https://docs.rs/ic-cdk-macros) - [JavaScript API reference](https://erxue-5aaaa-aaaab-qaagq-cai.ic0.app/) diff --git a/rust/basic_ethereum/README.md b/rust/basic_ethereum/README.md index 44e54fae5..0297369ca 100644 --- a/rust/basic_ethereum/README.md +++ b/rust/basic_ethereum/README.md @@ -1,13 +1,5 @@ ---- -keywords: [ advanced, rust, ethereum, eth, integration, ethereum integration ] ---- - # Basic Ethereum -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/basic_ethereum) - -## Overview - This tutorial will walk you through how to deploy a sample [canister smart contract](https://internetcomputer.org/docs/current/developer-docs/multi-chain/ethereum/overview) **that can send and receive Ether (ETH)** on the Internet Computer. @@ -22,9 +14,9 @@ features of the Internet Computer. For a deeper understanding of the ICP < > ETH integration, see the [Ethereum integration overview](https://internetcomputer.org/docs/current/developer-docs/multi-chain/ethereum/overview). -## Prerequisites +### Prerequisites -* [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). ## Step 1: Building and deploying sample code diff --git a/rust/canister-info/README.md b/rust/canister-info/README.md index 5342502bd..183429b8c 100644 --- a/rust/canister-info/README.md +++ b/rust/canister-info/README.md @@ -1,11 +1,5 @@ ---- -keywords: [beginner, rust, canister info] ---- - # Canister info -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/canister-info) - The purpose of this dapp is to give developers a small (backend) dapp that uses the IC's `canister_info` management call to retrieve information about canisters including canister history. You can find a detailed description of its methods in the form of doc comments in the source code. diff --git a/rust/canister-snapshots/README.md b/rust/canister-snapshots/README.md index 17dcb5dfc..2b222378b 100644 --- a/rust/canister-snapshots/README.md +++ b/rust/canister-snapshots/README.md @@ -1,12 +1,4 @@ ---- -keywords: [advanced, rust, backup, restore, snapshots] ---- - -# Canister Snapshots Example - -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/canister-snapshots) - -## Overview +# Canister snapshots This example demonstrates the process of taking and loading canister snapshots. It features a canister named `chat`, which functions as a miniature database. @@ -14,24 +6,23 @@ The `remove_spam` canister method intentionally includes a bug to simulate data The example outlines the steps to install the canister, create a snapshot, and subsequently restore the data after the simulated data loss. -## Prerequisites +### Prerequisites This example requires an installation of: -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). Note: the Canister Snapshots feature requires `dfx` version `0.23.0-beta.3` or later. +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). Note: the Canister Snapshots feature requires `dfx` version `0.23.0-beta.3` or later. - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -- ### Step 1: Begin by opening a terminal window and navigating into the project's directory +Begin by opening a terminal window. -```sh -cd examples/rust/canister-snapshots -``` +## Step 1: Setup the project environment -- ### Step 2: Start a clean local Internet Computer replica and a web server +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: -```sh -dfx stop -dfx start --clean + +```bash +cd examples/rust/canister-snapshots +dfx start ``` This terminal will stay blocked, printing log messages, until the `Ctrl+C` is pressed or `dfx stop` command is run. @@ -39,19 +30,18 @@ This terminal will stay blocked, printing log messages, until the `Ctrl+C` is pr Example output: ```sh -% dfx stop && dfx start --clean Running dfx start for version 0.23.0-beta.3 [...] Replica API running on 127.0.0.1:4943 ``` -- ### Step 3: Open another terminal window in the same directory +## Step 2: Open another terminal window in the same directory ```sh cd examples/rust/canister-snapshots ``` -- ### Step 4: Compile and deploy `chat` canister +## Step 3: Compile and deploy `chat` canister ```sh dfx deploy @@ -69,7 +59,7 @@ URLs: chat: http://127.0.0.1:4943/?canisterId=... ``` -- ### Step 5: Populate the database with data +## Step 4: Populate the database with data ```sh dfx canister call chat append 'Hi there!' @@ -85,7 +75,7 @@ Example output: (vec { "Hi there!" }) ``` -- ### Step 6: Take canister snapshot +## Step 5: Take canister snapshot Canister `chat` is currently running, and snapshots should not be taken of active canisters. Therefore, the canister should be stopped before taking a snapshot and then restarted. @@ -107,7 +97,7 @@ Created a new snapshot of canister chat. Snapshot ID: 00000000000000008000000000 Starting code for canister chat, with canister_id bkyz2-fmaaa-aaaaa-qaaaq-cai ``` -- ### Step 7: Simulate data loss +## Step 6: Simulate data loss The `remove_spam` canister method intentionally includes a bug to simulate data loss. @@ -127,7 +117,7 @@ Example output: There is no more data in the database. -- ### Step 8: Restore the canister state from the snapshot +## Step 7: Restore the canister state from the snapshot Canister `chat` is currently running, and snapshots should not be applied to active canisters. Therefore, the canister must be stopped before applying the snapshot and then restarted. diff --git a/rust/canister_logs/README.md b/rust/canister_logs/README.md index be2927f4c..38f0a52ae 100644 --- a/rust/canister_logs/README.md +++ b/rust/canister_logs/README.md @@ -1,123 +1,111 @@ ---- -keywords: [beginner, rust, canister logs, logging] ---- - # Canister logs -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/canister_logs) +### Prerequisites -## Prerequisites -This example requires an installation of: +- [x] Install the [IC + SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -- [x] DFX version 0.19.0 or newer -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/). -- [x] Download the following project files from GitHub: `git clone https://github.com/dfinity/examples/` +## Step 1: Setup project environment -You will need to have 3 terminal windows: -- Terminal A: Running a DFX instance and separating its output from anything else -- Terminal B: Deploying a canister and seeing its output -- Terminal C: Reading logs interactively +Navigate into the folder containing the project's files and start a local instance of the replica with the commandss: + +```shell +dfx start --clean +``` -### Step 1: Navigate into the folder containing the project's files and start a local instance of the replica with the command: +You will need to have 3 terminal windows: +- Terminal A: Running a `dfx` instance and separating its output from anything else. +- Terminal B: Deploying a canister and seeing its output. +- Terminal C: Reading logs interactively. ```shell # Terminal A -- for running DFX and separating its output from anything else. -$ cd examples/rust/canister_logs -$ dfx start --clean +cd examples/rust/canister_logs # Terminal B -- for deploying the canister and calling its methods. -$ cd examples/rust/canister_logs +cd examples/rust/canister_logs # Terminal C -- for polling logs. -$ cd examples/rust/canister_logs +cd examples/rust/canister_logs ``` -### Step 2: Deploy the canister: +## Step 2: Deploy the canister ```shell # Terminal B -$ dfx deploy +dfx deploy ``` -### Step 3: Check canister logs: +## Step 3: Check canister logs Expect to see logs from timer traps. ```shell # Terminal B -$ dfx canister logs canister_logs -[0. 2024-05-22T12:35:32.050252022Z]: right before timer trap -[1. 2024-05-22T12:35:32.050252022Z]: [TRAP]: timer trap -[2. 2024-05-22T12:35:37.680315152Z]: right before timer trap -[3. 2024-05-22T12:35:37.680315152Z]: [TRAP]: timer trap - +dfx canister logs CanisterLogs +[0. 2024-05-23T08:32:26.203980235Z]: right before timer trap +[1. 2024-05-23T08:32:26.203980235Z]: [TRAP]: timer trap +[2. 2024-05-23T08:32:31.836721763Z]: right before timer trap +[3. 2024-05-23T08:32:31.836721763Z]: [TRAP]: timer trap ``` -### Step 4: Call `print` method and check the logs: +## Step 4: Call `print` method and check the logs ```shell # Terminal B -$ dfx canister call canister_logs print hi +dfx canister call CanisterLogs print hi () # Expect to see new log entry. -$ dfx canister logs canister_logs +dfx canister logs CanisterLogs +... +[8. 2024-05-23T08:32:46.598972616Z]: right before timer trap +[9. 2024-05-23T08:32:46.598972616Z]: [TRAP]: timer trap +[10. 2024-05-23T08:32:48.713755238Z]: hi +[11. 2024-05-23T08:32:51.623988313Z]: right before timer trap +[12. 2024-05-23T08:32:51.623988313Z]: [TRAP]: timer trap ... -[18. 2024-05-22T12:36:20.881326098Z]: right before timer trap -[19. 2024-05-22T12:36:20.881326098Z]: [TRAP]: timer trap -[20. 2024-05-22T12:36:26.305162772Z]: hi -[21. 2024-05-22T12:36:27.185879186Z]: right before timer trap -[22. 2024-05-22T12:36:27.185879186Z]: [TRAP]: timer trap ``` -### Step 5: Start constantly polling logs: +## Step 5: Start constantly polling logs -In order not to call `dfx canister logs canister_logs` after every canister call in a separate terminal window/pane C start a script that will constantly poll logs: +In order not to call `dfx canister logs CanisterLogs` after every canister call in a separate terminal window/pane C start a script that will constantly poll logs: ```shell # Terminal C $ ./poll_logs.sh ... -[18. 2024-05-22T12:36:20.881326098Z]: right before timer trap -[19. 2024-05-22T12:36:20.881326098Z]: [TRAP]: timer trap -[20. 2024-05-22T12:36:26.305162772Z]: hi -[21. 2024-05-22T12:36:27.185879186Z]: right before timer trap -[22. 2024-05-22T12:36:27.185879186Z]: [TRAP]: timer trap +[8. 2024-05-23T08:32:46.598972616Z]: right before timer trap +[9. 2024-05-23T08:32:46.598972616Z]: [TRAP]: timer trap +[10. 2024-05-23T08:32:48.713755238Z]: hi +[11. 2024-05-23T08:32:51.623988313Z]: right before timer trap +[12. 2024-05-23T08:32:51.623988313Z]: [TRAP]: timer trap ... ``` -### Step 6: Call `print`, `trap` and other canister methods: +## Step 6: Call `print`, `trap` and other canister methods ```shell # Terminal B -$ dfx canister call canister_logs print hi! +dfx canister call CanisterLogs print hi! () -$ dfx canister call canister_logs print hello! +dfx canister call CanisterLogs print hello! () -$ dfx canister call canister_logs print yey! +dfx canister call CanisterLogs print yey! () -$ dfx canister call canister_logs trap oops! +dfx canister call CanisterLogs trap oops! Error: Failed update call. Caused by: Failed update call. The replica returned a rejection error: reject code CanisterError, reject message Canister bkyz2-fmaaa-aaaaa-qaaaq-cai trapped explicitly: oops!, error code None -$ dfx canister call canister_logs panic aaa! +dfx canister call CanisterLogs memory_oob Error: Failed update call. Caused by: Failed update call. - The replica returned a rejection error: reject code CanisterError, reject message Canister bkyz2-fmaaa-aaaaa-qaaaq-cai trapped explicitly: Panicked at 'aaa!', src/lib.rs:17:5, error code None - -$ dfx canister call canister_logs memory_oob -Error: Failed update call. -Caused by: Failed update call. - The replica returned a rejection error: reject code CanisterError, reject message Canister bkyz2-fmaaa-aaaaa-qaaaq-cai trapped: stable memory out of bounds, error code None - -$ dfx canister call canister_logs failed_unwrap -Error: Failed update call. -Caused by: Failed update call. - The replica returned a rejection error: reject code CanisterError, reject message Canister bkyz2-fmaaa-aaaaa-qaaaq-cai trapped explicitly: Panicked at 'called `Result::unwrap()` on an `Err` value: FromUtf8Error { bytes: [192, 255, 238], error: Utf8Error { valid_up_to: 0, error_len: Some(1) } }', src/lib.rs:31:47, error code None + The replica returned a rejection error: reject code CanisterError, reject message Canister bkyz2-fmaaa-aaaaa-qaaaq-cai trapped explicitly: StableMemory range out of bounds, error code None ``` @@ -126,30 +114,25 @@ Observe recorded logs that might look similar to this: ```shell # Terminal C ... -[45. 2024-05-22T12:37:33.0576873Z]: right before timer trap -[46. 2024-05-22T12:37:33.0576873Z]: [TRAP]: timer trap -[47. 2024-05-22T12:37:33.773343176Z]: hi! -[48. 2024-05-22T12:37:37.558075267Z]: hello! -[49. 2024-05-22T12:37:38.349121524Z]: right before timer trap -[50. 2024-05-22T12:37:38.349121524Z]: [TRAP]: timer trap -[51. 2024-05-22T12:37:41.466030479Z]: yey! -[52. 2024-05-22T12:37:43.7472275Z]: right before timer trap -[53. 2024-05-22T12:37:43.7472275Z]: [TRAP]: timer trap -[54. 2024-05-22T12:37:45.302285184Z]: right before trap -[55. 2024-05-22T12:37:45.302285184Z]: [TRAP]: oops! -[56. 2024-05-22T12:37:48.900425146Z]: right before timer trap -[57. 2024-05-22T12:37:48.900425146Z]: [TRAP]: timer trap -[58. 2024-05-22T12:37:49.736443986Z]: right before panic -[59. 2024-05-22T12:37:49.736443986Z]: Panicked at 'aaa!', src/lib.rs:37:5 -[60. 2024-05-22T12:37:49.736443986Z]: [TRAP]: Panicked at 'aaa!', src/lib.rs:37:5 -[61. 2024-05-22T12:37:54.122929037Z]: right before timer trap -[62. 2024-05-22T12:37:54.122929037Z]: [TRAP]: timer trap -[63. 2024-05-22T12:37:54.94948481Z]: right before memory out of bounds -[64. 2024-05-22T12:37:54.94948481Z]: [TRAP]: stable memory out of bounds -[65. 2024-05-22T12:37:59.693695919Z]: right before failed unwrap -[66. 2024-05-22T12:37:59.693695919Z]: Panicked at 'called `Result::unwrap()` on an `Err` value: FromUtf8Error { bytes: [192, 255, 238], error: Utf8Error { valid_up_to: 0, error_len: Some(1) } }', src/lib.rs:51:47 -[67. 2024-05-22T12:37:59.693695919Z]: [TRAP]: Panicked at 'called `Result::unwrap()` on an `Err` value: FromUtf8Error { bytes: [192, 255, 238], error: Utf8Error { valid_up_to: 0, error_len: Some(1) } }', src/lib.rs:51:47 -[68. 2024-05-22T12:38:00.621855713Z]: right before timer trap -[69. 2024-05-22T12:38:00.621855713Z]: [TRAP]: timer trap +[19. 2024-05-23T08:33:11.319493785Z]: right before timer trap +[20. 2024-05-23T08:33:11.319493785Z]: [TRAP]: timer trap +[21. 2024-05-23T08:33:14.229855179Z]: hi! +[22. 2024-05-23T08:33:16.413512126Z]: right before timer trap +[23. 2024-05-23T08:33:16.413512126Z]: [TRAP]: timer trap +[24. 2024-05-23T08:33:18.622686552Z]: hello! +[25. 2024-05-23T08:33:21.519088681Z]: right before timer trap +[26. 2024-05-23T08:33:21.519088681Z]: [TRAP]: timer trap +[27. 2024-05-23T08:33:22.96101893Z]: yey! +[28. 2024-05-23T08:33:26.601860526Z]: right before timer trap +[29. 2024-05-23T08:33:26.601860526Z]: [TRAP]: timer trap +[30. 2024-05-23T08:33:28.039227914Z]: right before trap +[31. 2024-05-23T08:33:28.039227914Z]: [TRAP]: oops! +[32. 2024-05-23T08:33:31.634215234Z]: right before timer trap +[33. 2024-05-23T08:33:31.634215234Z]: [TRAP]: timer trap +[34. 2024-05-23T08:33:35.96761902Z]: right before memory out of bounds +[35. 2024-05-23T08:33:35.96761902Z]: [TRAP]: StableMemory range out of bounds +[36. 2024-05-23T08:33:36.712223153Z]: right before timer trap +[37. 2024-05-23T08:33:36.712223153Z]: [TRAP]: timer trap ... -``` + +``` \ No newline at end of file diff --git a/rust/composite_query/README.md b/rust/composite_query/README.md index 530a30111..82c6b267b 100644 --- a/rust/composite_query/README.md +++ b/rust/composite_query/README.md @@ -1,17 +1,18 @@ ---- -keywords: [intermediate, rust, composite query, queries] ---- - # Composite queries -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/composite_query) +### Prerequisites +This example requires an installation of: + +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` + +Begin by opening a terminal window. -## Building the example +## Step 1: Setup the project environment We first need to build the data partition backend canister. ```bash -git clone https://github.com/dfinity/examples cd examples/rust/composite_query dfx start --background dfx canister create data_partition @@ -26,7 +27,7 @@ dfx build kv_frontend dfx canister install kv_frontend ``` -## Using the canister +## Step 2: Using the canister Now we add some key value pairs via the frontend canister. diff --git a/rust/counter/README.md b/rust/counter/README.md index 0206f18ec..2f2ab37b6 100644 --- a/rust/counter/README.md +++ b/rust/counter/README.md @@ -1,12 +1,8 @@ ---- -keywords: [beginner, rust, counter] ---- - # Counter -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/counter) +This example demonstrates a counter application. -## Prerequisites +### Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/). @@ -14,38 +10,41 @@ This example requires an installation of: Begin by opening a terminal window. -### Step 1: Navigate into the folder containing the project's files and start a local instance of the replica with the command: +## Step 1: Setup the project environment + +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: + ```bash cd examples/rust/counter dfx start --background ``` -### Step 2: Test the canister: +## Step 2: Test the canister ```bash cargo test ``` -### Step 3: Deploy the canister: +## Step 3: Deploy the canister ```bash dfx deploy ``` -### Step 4: Set the value of the counter: +## Step 4: Set the value of the counter ```bash dfx canister call counter set '(7)' ``` -### Step 5: Increment the value of the counter: +## Step 5: Increment the value of the counter ```bash dfx canister call counter inc ``` -### Step 6: Get the value of the counter: +## Step 6: Get the value of the counter ```bash dfx canister call counter get diff --git a/rust/defi/README.md b/rust/defi/README.md index 8d2b6a6a4..40ab42db7 100644 --- a/rust/defi/README.md +++ b/rust/defi/README.md @@ -4,7 +4,7 @@ To enable DeFi applications on the IC, canisters need to interact with token canisters and the ledger canister. This sample dapp illustrates how to facilitate these interactions. You can see a quick introduction on [YouTube](https://youtu.be/fLbaOmH24Gs). -The sample exchange is implemented in [Motoko](https://github.com/dfinity/examples/tree/master/motoko/defi) and [Rust](https://github.com/dfinity/examples/tree/master/rust/defi) and can be seen [running on the IC](https://gzz56-daaaa-aaaal-qai2a-cai.ic0.app/). +The sample exchange is implemented in [Rust](https://github.com/dfinity/examples/tree/master/rust/defi) and can be seen [running on the IC](https://gzz56-daaaa-aaaal-qai2a-cai.ic0.app/). ## Architecture @@ -79,19 +79,16 @@ After depositing funds to the exchange, the user can place orders. An order cons Compared to depositing funds, withdrawing funds is simpler. Since the exchange has custody of the funds, the exchange will send funds back to the user on `withdraw` requests. The internal exchange balances are adjusted accordingly. ## Prerequisites -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). - [x] Download [cmake](https://cmake.org/). -- [x] Download [npm](https://nodejs.org/en/download/). -- [x] If you want to deploy the Rust version, make sure you add Wasm as a target: +- [x] Add Wasm as a target: `rustup target add wasm32-unknown-unknown` - ## Step 1: Download the project's GitHub repo and install the dependencies: -``` +```bash git clone --recurse-submodules --shallow-submodules https://github.com/dfinity/examples.git -# for the rust implementation examples/rust/defi -cd examples/motoko/defi +cd examples/rust/defi make install ``` @@ -105,35 +102,31 @@ http://127.0.0.1:4943?canisterId=by6od-j4aaa-aaaaa-qaadq-cai or you can regenerate the URL "http://127.0.0.1:4943?canisterId=$(dfx canister id frontend)". Open this URL in a web browser. -## Step 2: To interact with the exchange, you can create a local Internet Identity by clicking the login button. +## Step 2: Create a local Internet Identity by clicking the login button This sample project uses a local test version of Internet Identity. Do not use your mainnet Internet Identity, and this testnet Internet Identity will not work on the mainnet. -## Step 3: When prompted, select **Create Internet Identity**. - +## Step 3: When prompted, select **Create Internet Identity** -## Step 4: Then select **Create Passkey**. +## Step 4: Then select **Create Passkey** -## Step 5: Complete the CAPTCHA. +## Step 5: Complete the CAPTCHA -## Step 6: Save the II number and click **I saved it, continue**. +## Step 6: Save the II number and click **I saved it, continue** -## Step 7: You will be redirected to the exchange's frontend webpage. +You will be redirected to the exchange's frontend webpage +## Step 7: Get tokens -## Step 8: You can give yourself some tokens and ICP by running an initialization script with your II principal that you can copy from the frontend. - - -## Step 9: Then run the following command: +You can give yourself some tokens and ICP by running an initialization script with your II principal that you can copy from the frontend `make init-local II_PRINCIPAL=` -## Step 10: Refresh the web browser to verify that your tokens were deposited. - +## Step 8: Refresh the web browser to verify that your tokens were deposited. To trade tokens with yourself, you can open a second incognito browser window. diff --git a/rust/dip721-nft-container/README.md b/rust/dip721-nft-container/README.md index ed4157991..016d35ffa 100644 --- a/rust/dip721-nft-container/README.md +++ b/rust/dip721-nft-container/README.md @@ -1,18 +1,12 @@ ---- -keywords: [advanced, rust, nft, dip721] ---- - # DIP721 NFT -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/dip721-nft-container) - This example demonstrates implementing an NFT canister. NFTs (non-fungible tokens) are unique tokens with arbitrary metadata, usually an image of some kind, to form the digital equivalent of trading cards. There are a few different NFT standards for the Internet Computer (e.g [EXT](https://github.com/Toniq-Labs/extendable-token), [IC-NFT](https://github.com/rocklabs-io/ic-nft)), but this tutorial will use [DIP-721](https://github.com/Psychedelic/DIP721). You can see a quick introduction on [YouTube](https://youtu.be/1po3udDADp4). The canister is a basic implementation of the standard, with support for the minting, burning, and notification interface extensions. -The sample code is available in the [samples repository](https://github.com/dfinity/examples) in [Rust](https://github.com/dfinity/examples/tree/master/rust/dip721-nft-container) and [Motoko](https://github.com/dfinity/examples/tree/master/motoko/dip721-nft-container). +The sample code is available in the [samples repository](https://github.com/dfinity/examples) in [Rust](https://github.com/dfinity/examples/tree/master/rust/dip721-nft-container). Command-line length limitations would prevent you from minting an NFT with a large file, like an image or video, via `dfx`. To that end, there is a [command-line minting tool](https://github.com/dfinity/experimental-minting-tool) provided for minting simple NFTs. @@ -94,24 +88,23 @@ It contains six NFTs, so you can look at items from `/0/0` to `/` wi Remember that query functions are uncertified; the result of functions like `ownerOfDip721` can be modified arbitrarily by a single malicious node. If queried information is depended on, for example, if someone might send ICP to the owner of a particular NFT to buy it from them, those calls should be performed as update calls instead. You can force an update call by passing the `--update` flag to `dfx` or using the `Agent::update` function in `agent-rs`. - ### Step 5: Mint an NFT. +### Step 4: Mint an NFT Due to size limitations on the length of a terminal command, an image- or video-based NFT would be impossible to send via `dfx`. To that end, there is an experimental [minting tool](https://github.com/dfinity/experimental-minting-tool) you can use to mint a single-file NFT. diff --git a/rust/face-recognition/README.md b/rust/face-recognition/README.md index 1305fc352..17bc0b97c 100644 --- a/rust/face-recognition/README.md +++ b/rust/face-recognition/README.md @@ -1,11 +1,11 @@ -# ICP Face Recognition +# ICP face recognition This is an ICP smart contract runs face detection and face recognition of user's photo that can be uploaded either from a camera or a local file. The smart contract consists of two canisters: -- the backend canister embeds the [the Tract ONNX inference engine](https://github.com/sonos/tract) with two ONNX models. One model is used to detect a face in the photo and return its bounding box. Another model is used for computing face embeddings. -- the frontend canister contains the Web assets such as HTML, JS, CSS that are served to the browser. +- The backend canister embeds the [the Tract ONNX inference engine](https://github.com/sonos/tract) with two ONNX models. One model is used to detect a face in the photo and return its bounding box. Another model is used for computing face embeddings. +- The frontend canister contains the Web assets such as HTML, JS, CSS that are served to the browser. # Models @@ -17,6 +17,7 @@ A face detection model finds the bounding box of a face in the image. You can download [Ultraface](https://github.com/onnx/models/tree/main/validated/vision/body_analysis/ultraface) - ultra-lightweight face detection model - [[here](https://github.com/onnx/models/blob/bec48b6a70e5e9042c0badbaafefe4454e072d08/validated/vision/body_analysis/ultraface/models/version-RFB-320.onnx)]. Alternatively, you can run + ``` ./download-face-detection-model.sh ``` @@ -26,17 +27,18 @@ Alternatively, you can run A face recognition model computes a vector embedding of an image with a face. You can obtain a pretrained model from [facenet-pytorch](https://github.com/timesler/facenet-pytorch) as follows. +- #### Step 1: Install `python` and `pip`: https://packaging.python.org/en/latest/tutorials/installing-packages/. -1. Install `python` and `pip`: https://packaging.python.org/en/latest/tutorials/installing-packages/. +- #### Step 2: Install `facenet-pytorch` and `torch`: -2. Install `facenet-pytorch` and `torch`: ``` pip install facenet-pytorch pip install torch pip install onnx ``` -3. Export ONNX model. Start a python shell and run the following commands or create a python file and run it: +- #### Step 3: Export ONNX model. Start a python shell and run the following commands or create a python file and run it: + ``` import torch import facenet_pytorch @@ -45,29 +47,17 @@ input = torch.randn(1, 3, 160, 160) torch.onnx.export(resnet, input, "face-recognition.onnx", verbose=False, opset_version=11) ``` -4. This should produce `face-recognition.onnx`. Copy the file to the root of this repository. - -# Dependencies - -Install `dfx`, Rust, etc: https://internetcomputer.org/docs/current/developer-docs/getting-started/hello-world - -Install `wasi2ic`: -- Follow the steps in https://github.com/wasm-forge/wasi2ic -- Make sure that `wasi2ic` binary is in your `$PATH`. - -Install NodeJS dependencies for the frontend: +- #### Step 4: This should produce `face-recognition.onnx`. Copy the file to the root of this repository. -``` -npm install -``` - -Install `wasm-opt`: +### Prerequisites -``` -cargo install wasm-opt -``` +- [x] Install the [IC + SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` +- [x] Install `wasi2ic`: Follow the steps in https://github.com/wasm-forge/wasi2ic and make sure that `wasi2ic` binary is in your `$PATH`. +- [x] Install `wasm-opt`: `cargo install wasm-opt` -# Build +## Build the application ``` dfx start --background @@ -77,7 +67,7 @@ dfx deploy If the deployment is successful, the it will show the `frontend` URL. Open that URL in browser to interact with the smart contract. -# Chunk uploading of models +## Chunk uploading of models Since the models are large, they cannot be embedded into the Wasm binary of the smart contract. Instead they should be uploaded separately. @@ -91,6 +81,7 @@ cargo install ic-file-uploader ``` Afterwards, execute the `upload-models-to-canister.sh` script, which runs the following commands: + ``` dfx canister call backend clear_face_detection_model_bytes dfx canister call backend clear_face_recognition_model_bytes @@ -99,7 +90,7 @@ ic-file-uploader backend append_face_recognition_model_bytes face-recognition.on dfx canister call backend setup_models ``` -# Credits +## Credits Thanks to [DecideAI](https://decideai.xyz/) for discussions and providing [ic-file-uploader](https://github.com/modclub-app/ic-file-uploader/tree/main). diff --git a/rust/guards/README.md b/rust/guards/README.md index 8fc09fb5a..b1f65d454 100644 --- a/rust/guards/README.md +++ b/rust/guards/README.md @@ -1,14 +1,14 @@ -# Guards and Async Code +# Guards and async code ## Summary -This example canister shows some advanced behaviour between guards and asynchronous code. This example is meant for Rust +This example canister shows some advanced behavior between guards and asynchronous code. This example is meant for Rust canister developers that are already familiar with [asynchronous code](https://internetcomputer.org/docs/current/developer-docs/smart-contracts/advanced-features/async-code/) and the security best-practices related to [inter-canister calls and rollbacks](https://internetcomputer.org/docs/current/developer-docs/security/rust-canister-development-security-best-practices#inter-canister-calls-and-rollbacks). -## Guard to Maintain Invariants +## Guard to maintain invariants This example canister stores a bunch of items on the heap, where each item is simply modelled as a `String`. One invariant that the canister aims at maintaining is that each item is **processed at most once**, where processing an @@ -19,7 +19,7 @@ One tricky part in this scenario is that an item can therefore only be marked as has completed, meaning in the callback. As mentioned in the [security best-practices](https://internetcomputer.org/docs/current/developer-docs/security/rust-canister-development-security-best-practices#securely-handle-traps-in-callbacks), it's not always feasible to guarantee that the callback will not trap, which in that case would break the invariant due -to the state being rollbacked. +to the state being rolled back. The standard solution to maintain such an invariant, despite a potential panic in the callback is to use a guard. However, this example canister shows that it's also crucially important that the declaration of the guard happens in @@ -27,41 +27,41 @@ another message than the callback, which is the case for true asynchronous code etc.). It's in particular not enough to `await` a function that's declared to be `async`, since if the future can polled until completion directly, everything will be executed in a single message. -## Automated Integration Tests +## Automated integration tests -To run the integration tests under `tests/` install [PocketIC server](https://github.com/dfinity/pocketic) and then run +To run the integration tests under `tests/` install [PocketIC server](https://github.com/dfinity/pocketic) and then run: ```shell cargo build --target wasm32-unknown-unknown --release && cargo test ``` -## Manual Testing with `dfx` +## Manual testing with `dfx` ### Setup -Start `dfx` +Start `dfx`: ```shell dfx start --background ``` -and then proceed to deploying the canister +Deploy the canister: ```shell dfx deploy ``` -You should now be able to query the canister, e.g., to check if an item is processed +You should now be able to query the canister, e.g., to check if an item is processed: ```shell dfx canister call guards is_item_processed 'mint' ``` -which should return `(null)` since the canister currently has an empty state. +This should return `(null)` since the canister currently has an empty state. ### Test -As an example, we show how the behaviour tested in `should_process_single_item_and_mark_it_as_processed` can be tested +As an example, we show how the behavior tested in `should_process_single_item_and_mark_it_as_processed` can be tested manually. Set the item `"mint"` to be processed: @@ -84,7 +84,7 @@ Process the item by calling the *panicking* callback: dfx canister call guards process_single_item_with_panicking_callback '("mint", variant { TrueAsyncCall })' ``` -Since the queried endpoint panicks on purpose, expect some error message similar to +Since the queried endpoint panics on purpose, expect some error message similar to: ```text 2024-05-29 11:54:39.817800 UTC: [Canister bkyz2-fmaaa-aaaaa-qaaaq-cai] Panicked at 'panicking callback!', src/lib.rs:47:5 @@ -93,10 +93,10 @@ Caused by: Failed update call. The replica returned a rejection error: reject code CanisterError, reject message Canister bkyz2-fmaaa-aaaaa-qaaaq-cai trapped explicitly: Panicked at 'panicking callback!', src/lib.rs:47:5, error code None ``` -Ensure that the guard was executed to ensure that the item is marked as processed despite the previous panic +Ensure that the guard was executed to ensure that the item is marked as processed despite the previous panic: ```shell dfx canister call guards is_item_processed 'mint' ``` -should return `(opt true)`. +This should return `(opt true)`. diff --git a/rust/hello/README.md b/rust/hello/README.md index 5be675357..b093d864a 100644 --- a/rust/hello/README.md +++ b/rust/hello/README.md @@ -1,12 +1,5 @@ ---- -keywords: [beginner, rust, hello] ---- - # Hello, world! -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/hello) - -## Overview This sample demonstrates a simple dapp consisting of two canisters: - A simple backend canister, `hello`, implementing the logic of the application. @@ -19,9 +12,9 @@ It is the dapp equivalent of the ubiquitous 'Hello, world!' and can be seen runn This sample is based on the default project created by running `dfx new` as described in the quick start documents. -The sample code is available from the [samples](https://github.com/dfinity/examples) repository in both [Motoko](https://github.com/dfinity/examples/tree/master/motoko/hello) and [Rust](https://github.com/dfinity/examples/tree/master/rust/hello). +The sample code is available from the [samples](https://github.com/dfinity/examples) repository in [Rust](https://github.com/dfinity/examples/tree/master/rust/hello). -Canister `hello`, whether implemented in Motoko or Rust, presents the same Candid interface: +Canister `hello` presents the following Candid interface: ```candid service : { greet: (text) -> (text); @@ -36,53 +29,42 @@ The frontend canister and its assets are identical for both projects. 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. +- A simple backend canister, hello, implementing the logic of the application in Rust. - 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`. This example is based on the default project created by running `dfx new --type=rust hello`. -### Prerequisites +### Prerequisites + This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). -- [x] Install `node.js` (to build the web frontend). - - ### Step 1: Open a terminal window. -If you haven't already, create a default project with the command: -``` -dfx new --type=rust hello -cd hello -``` +## Step 1: Open a terminal window - ### Step 2: Start a local canister execution environment: +Start an instance of the local replica and create a default project with the command: ``` dfx start --background +dfx new --type=rust hello +cd hello ``` - ### Step 3: Ensure that the required node modules are available in your project directory, if needed, by running the following command: - -``` -npm install -``` - - ### Step 4: Register, build, and deploy the project with the command: +## Step 2: Register, build, and deploy the project ``` dfx deploy -npm start ``` - ### Step 5: Call the hello canister's greet function: +## Step 3: Call the hello canister's `greet` function ``` dfx canister call hello_backend greet everyone ``` - ### Step 6: Observe the following result: +## Step 4: Observe the following result ``` ("Hello, everyone!") @@ -90,16 +72,17 @@ dfx canister call hello_backend greet 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: - ### Step 7: Determine the URL of the hello_frontend asset canister. +## Step 5: Determine the URL of the hello_frontend asset canister ``` echo "http://localhost:8000/?canisterId=$(dfx canister id hello_frontend)" ``` - ### Step 8: Navigate to the URL in your browser. +## Step 6: Navigate to the URL in your browser + The browser should display a simple HTML page with a sample asset image file, an input field, and a button. - ### Step 9: Enter the text "everyone" and click the button to see the greeting returned by the backend hello canister. +## Step 7: 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 content, you may need to clear your browser cache. diff --git a/rust/icp_transfer/README.md b/rust/icp_transfer/README.md index d3f266c65..f4dbe96bd 100644 --- a/rust/icp_transfer/README.md +++ b/rust/icp_transfer/README.md @@ -1,9 +1,5 @@ # ICP transfer -[View this samples code on GitHub](https://github.com/dfinity/examples/tree/master/rust/icp_transfer). - -## Overview - ICP transfer is a canister that can transfer ICP from its account to other accounts. It is an example of a canister that uses the ledger canister. Sample code is available in [Motoko](https://github.com/dfinity/examples/tree/master/motoko/icp_transfer) and [Rust](https://github.com/dfinity/examples/tree/master/rust/icp_transfer). :::info @@ -17,54 +13,42 @@ The sample code revolves around one core transfer function which takes as input This sample will use the Rust variant. -## Prerequisites - -This example requires an installation of: - -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). -- [x] Download and install [git.](https://git-scm.com/downloads) - -## How to get there - -The following steps will guide you through the process of setting up the token transfer canister for your own project. +### Prerequisites -:::info - -If you just want to interact with this example, follow steps 4-8 and 10-13 below. +- [x] Install the [IC + SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. -::: +## Step 1: Setup project environment -### Step 1: Create a new `dfx` project and navigate into the project's directory. +Start a local instance of the replica and create a new project with the commands: -```bash +``` +dfx start --background dfx new --type=rust icp_transfer --no-frontend cd icp_transfer ``` ### Step 2: Determine ledger file locations -:::info +> [!TIP] +> You can read more about how to [setup the ICP ledger locally](https://internetcomputer.org/docs/current/developer-docs/defi/icp-tokens/ledger-local-setup). -You can read more about how to [setup the ICP ledger locally](https://internetcomputer.org/docs/current/developer-docs/defi/icp-tokens/ledger-local-setup). +Go to the [releases overview](https://dashboard.internetcomputer.org/releases) and copy the latest replica binary revision. -::: - -Go to the [releases overview](https://dashboard.internetcomputer.org/releases) and copy the latest replica binary revision. At the time of writing, this is `d87954601e4b22972899e9957e800406a0a6b929`. - -The URL for the ledger Wasm module is `https://download.dfinity.systems/ic//canisters/ledger-canister.wasm.gz`, so with the above revision it would be `https://download.dfinity.systems/ic/d87954601e4b22972899e9957e800406a0a6b929/canisters/ledger-canister.wasm.gz`. +The URL for the ledger Wasm module is `https://download.dfinity.systems/ic//canisters/ledger-canister.wasm.gz`. -The URL for the ledger.did file is `https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icp_ledger/ledger.did`, so with the above revision it would be `https://raw.githubusercontent.com/dfinity/ic/d87954601e4b22972899e9957e800406a0a6b929/rs/rosetta-api/icp_ledger/ledger.did`. +The URL for the ledger.did file is `https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icp_ledger/ledger.did`. [OPTIONAL] If you want to make sure you have the latest ICP ledger files, you can run the following script. Please ensure that you have [`jq`](https://jqlang.github.io/jq/) installed as the script relies on it. ```sh -curl -o download_latest_icp_ledger.sh "https://raw.githubusercontent.com/dfinity/ic/00a4ab409e6236d4082cee4a47544a2d87b7190d/rs/rosetta-api/scripts/download_latest_icp_ledger.sh" +curl -o download_latest_icp_ledger.sh "https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/scripts/download_latest_icp_ledger.sh" chmod +x download_latest_icp_ledger.sh ./download_latest_icp_ledger.sh ``` -### Step 3: Configure the `dfx.json` file to use the ledger : +## Step 3: Configure the `dfx.json` file to use the ledger Replace its contents with this but adapt the URLs to be the ones you determined in step 2: @@ -78,8 +62,8 @@ Replace its contents with this but adapt the URLs to be the ones you determined }, "icp_ledger_canister": { "type": "custom", - "candid": "https://raw.githubusercontent.com/dfinity/ic/d87954601e4b22972899e9957e800406a0a6b929/rs/rosetta-api/icp_ledger/ledger.did", - "wasm": "https://download.dfinity.systems/ic/d87954601e4b22972899e9957e800406a0a6b929/canisters/ledger-canister.wasm.gz", + "candid": "https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icp_ledger/ledger.did", + "wasm": "https://download.dfinity.systems/ic//canisters/ledger-canister.wasm.gz", "remote": { "id": { "ic": "ryjl3-tyaaa-aaaaa-aaaba-cai" @@ -98,13 +82,7 @@ Replace its contents with this but adapt the URLs to be the ones you determined } ``` -### Step 4: Start a local replica: - -```bash -dfx start --background --clean -``` - -### Step 5: Create a new identity that will work as a minting account: +## Step 4: Create a new identity that will work as a minting account ```bash dfx identity new minter --storage-mode plaintext @@ -115,14 +93,14 @@ export MINTER_ACCOUNT_ID=$(dfx ledger account-id) > [!IMPORTANT] > Transfers from the minting account will create Mint transactions. Transfers to the minting account will create Burn transactions. -### Step 6: Switch back to your default identity and record its ledger account identifier: +## Step 5: Switch back to your default identity and record its ledger account identifier ```bash dfx identity use default export DEFAULT_ACCOUNT_ID=$(dfx ledger account-id) ``` -### Step 7: Deploy the ledger canister to your network: +## Step 6: Deploy the ledger canister to your network Take a moment to read the details of the call made below. Not only are you deploying the ICP ledger canister, you are also: @@ -165,7 +143,7 @@ URLs: icp_ledger_canister: http://127.0.0.1:4943/?canisterId=bnz7o-iuaaa-aaaaa-qaaaa-cai&id=ryjl3-tyaaa-aaaaa-aaaba-cai ``` -### Step 8: Verify that the ledger canister is healthy and working as expected by using the command: +## Step 7: Verify that the ledger canister is healthy and working as expected ```bash dfx canister call icp_ledger_canister account_balance '(record { account = '$(python3 -c 'print("vec{" + ";".join([str(b) for b in bytes.fromhex("'$DEFAULT_ACCOUNT_ID'")]) + "}")')'})' @@ -177,7 +155,7 @@ The output should be: (record { e8s = 10_000_000_000 : nat64 }) ``` -### Step 9: Prepare the token transfer canister: +## Step 8: Prepare the token transfer canister Replace the contents of the `src/icp_transfer_backend/Cargo.toml` file with the following: @@ -275,26 +253,23 @@ service : { ``` -### Step 10: Deploy the token transfer canister: +## Step 9: Deploy the token transfer canister ```bash dfx deploy icp_transfer_backend ``` -### Step 11: Determine out the address of your canister: +## Step 10: Determine out the address of your canister ```bash TOKENS_TRANSFER_ACCOUNT_ID="$(dfx ledger account-id --of-canister icp_transfer_backend)" TOKENS_TRANSFER_ACCOUNT_ID_BYTES="$(python3 -c 'print("vec{" + ";".join([str(b) for b in bytes.fromhex("'$TOKENS_TRANSFER_ACCOUNT_ID'")]) + "}")')" ``` -### Step 12: Transfer funds to your canister: - -:::info +## Step 11: Transfer funds to your canister -Make sure that you are using the default `dfx` account that we minted tokens to in step 7 for the following steps. - -::: +> [!TIP] +> Make sure that you are using the default `dfx` account that we minted tokens to in step 7 for the following steps. Make the following call to transfer funds to the canister: @@ -308,7 +283,7 @@ If successful, the output should be: (variant { Ok = 1 : nat64 }) ``` -### Step 13: Transfer funds from the canister: +## Step 12: Transfer funds from the canister Now that the canister owns ICP on the ledger, you can transfer funds from the canister to another account, in this case back to the default account: diff --git a/rust/image-classification/README.md b/rust/image-classification/README.md index 500a95bc0..49432d7d6 100644 --- a/rust/image-classification/README.md +++ b/rust/image-classification/README.md @@ -1,4 +1,4 @@ -# ICP Image Classification +# ICP image classification This is an ICP smart contract that accepts an image from the user and runs image classification inference. The smart contract consists of two canisters: @@ -10,42 +10,19 @@ The smart contract consists of two canisters: This example uses Wasm SIMD instructions that are available in `dfx` version `0.20.2-beta.0` or newer. -# Dependencies +## Prerequisites -Install `dfx`, Rust, etc: https://internetcomputer.org/docs/current/developer-docs/getting-started/hello-world +- [x] Install the [IC + SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` +- [x] Install WASI SDK 21: + - [x] Install `wasi-skd-21.0` from https://github.com/WebAssembly/wasi-sdk/releases/tag/wasi-sdk-21 + - [x] Export `CC_wasm32_wasi` in your shell such that it points to WASI clang and sysroot. Example: `export CC_wasm32_wasi="/path/to/wasi-sdk-21.0/bin/clang --sysroot=/path/to/wasi-sdk-21.0/share/wasi-sysroot` +- [x] Install `wasi2ic`: Follow the steps in https://github.com/wasm-forge/wasi2ic and make sure that `wasi2ic` binary is in your `$PATH`. +- [x] Download MobileNet v2-7 to `src/backend/assets/mobilenetv2-7.onnx`: `./downdload_model.sh` +- [x] Install `wasm-opt`: `cargo install wasm-opt` -Install WASI SDK 21: - -- Install `wasi-skd-21.0` from https://github.com/WebAssembly/wasi-sdk/releases/tag/wasi-sdk-21 -- Export `CC_wasm32_wasi` in your shell such that it points to WASI clang and sysroot. Example: - -``` -export CC_wasm32_wasi="/path/to/wasi-sdk-21.0/bin/clang --sysroot=/path/to/wasi-sdk-21.0/share/wasi-sysroot" -``` - -Install `wasi2ic`: -- Follow the steps in https://github.com/wasm-forge/wasi2ic -- Make sure that `wasi2ic` binary is in your `$PATH`. - -Download MobileNet v2-7 to `src/backend/assets/mobilenetv2-7.onnx`: - -``` -./downdload_model.sh -``` - -Install NodeJS dependencies for the frontend: - -``` -npm install -``` - -Install `wasm-opt`: - -``` -cargo install wasm-opt -``` - -# Build +## Build the application ``` dfx start --background diff --git a/rust/nft-wallet/README.md b/rust/nft-wallet/README.md index 2309eb417..23652a33a 100644 --- a/rust/nft-wallet/README.md +++ b/rust/nft-wallet/README.md @@ -1,24 +1,16 @@ ---- -keywords: [advanced, rust, nft, dip721] ---- - # NFT wallet -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/nft-wallet) - -## Overview - This is an NFT wallet example dapp that utilizes minted NFTs from the Rust dip721-nft-container. Among some of its essential features, the wallet can register NFTs, transfer out NFTs, and check how many NFTs it contains. This dapp includes a frontend UI for interaction. -## Prerequisites -This example requires an installation of: +### Prerequisites -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). +- [x] Install the [IC + SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -Begin by opening a terminal window. +## Step 1: Setup project environment -### Step 1: You can deploy the dapp using the `start.sh` script: +You can deploy the dapp using the `start.sh` script: ```bash cd examples/rust/nft-wallet @@ -38,13 +30,13 @@ cd .. ./deploy.sh ``` -### Step 2: If you'd like to deploy on the IC network run the command: +If you'd like to deploy on the mainnet, run the command: ```bash ./deploy.sh --network ic ``` -### Step 3: Make calls against NFT wallet canister: +## Step 2: Make calls against NFT wallet canister For example, to to transfer an NFT use the command: diff --git a/rust/parallel_calls/README.md b/rust/parallel_calls/README.md index 3e0bba4f4..95db32030 100644 --- a/rust/parallel_calls/README.md +++ b/rust/parallel_calls/README.md @@ -1,13 +1,5 @@ ---- -keywords: [advanced, rust, defi] ---- - # Parallel inter-canister calls -[View this sample code on GitHub](https://github.com/dfinity/examples/tree/master/rust/parallel_calls). - -## Overview - This example demonstrates how to implement inter-canister calls that run in parallel in Rust, and highlights some differences between parallel and sequential calls. Running independent calls in parallel can lower the latency, especially when messages are sent across subnets. For example, a canister that swaps two tokens might want to launch both token transfer operations in parallel. ## Architecture @@ -18,38 +10,37 @@ The sample code revolves around two simple canisters, `caller` and `callee`. `Ca The callee exposes a simple `ping` endpoint that takes no parameters and returns nothing. -## Prerequisites +### Prerequisites -To run this example you should: - -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). +- [x] Install the [IC + SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -## Running the example - Begin by opening a terminal window. -### Step 1: Navigate into the example folder and start a local Internet Computer replica +## Step 1: Setup project environment + +Navigate into the folder containing the project's files and start a local instance of the replica with the commands: ```bash cd examples/rust/parallel_calls dfx start --background ``` -### Step 2: Deploy the canister +## Step 2: Deploy the canisters ```bash dfx deploy ``` -### Step 3: Set up the caller canister +## Step 3: Set up the caller canister We now provide the ID of the callee to the caller, such that the caller can initiate calls. ``` dfx canister call caller setup_callee "(principal \"`dfx canister id callee`\")" ``` -### Step 4: Invoke sequential and parallel calls +## Step 4: Invoke sequential and parallel calls Let's first call the different endpoints of the `caller` canister using `dfx` @@ -102,7 +93,7 @@ All the sequential calls succeed, but most parallel calls fail. The reason is th Lastly, the parallel calls here complete sooner -- because most of them fail! -### Step 5: Multi-subnet setting +## Step 5: Multi-subnet setting Parallel calls are a lot more useful in multi-subnet settings. We can create such a setting locally using Pocket IC. diff --git a/rust/performance_counters/README.md b/rust/performance_counters/README.md index a158c2e6e..218fab4b6 100644 --- a/rust/performance_counters/README.md +++ b/rust/performance_counters/README.md @@ -1,14 +1,6 @@ ---- -keywords: [intermediate, rust, performance, canister performance, counter] ---- - # Performance counter -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/performance_counters) - -## Overview - -The canister can query one of the "performance counters", which is a deterministic monotonically increasing integer approximating the amount of work the canister has done. Developers might use this data to profile and optimize the canister performance. +A canister can query one of the "performance counters", which is a deterministic monotonically increasing integer approximating the amount of work the canister has done. Developers might use this data to profile and optimize the canister performance. ```Candid ic0.performance_counter : (counter_type : i32) -> i64 @@ -39,21 +31,18 @@ In the future, ICP might expose more performance counters. ## Prerequisites -This example requires an installation of: +## Prerequisites -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). +- [x] Install the [IC + SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -### Step 1: Begin by opening a terminal window and navigating into the project's directory - -```sh -cd examples/rust/performance_counters -``` +## Step 1: Setup project environment -### Step 2: Start a clean local Internet Computer replica and a web server +Navigate into the folder containing the project's files and start a local instance of the replica with the command: ```sh -dfx stop +cd examples/rust/performance_counters dfx start --clean ``` @@ -62,18 +51,18 @@ This terminal will stay blocked, printing log messages, until the `Ctrl+C` is pr Example output: ```sh -% dfx stop && dfx start --clean +dfx start --clean [...] Dashboard: http://localhost:63387/_/dashboard ``` -### Step 3: Open another terminal window in the same directory +## Step 2: Open another terminal window in the same directory ```sh cd examples/rust/performance_counters ``` -### Step 4: Compile and deploy `performance_counters` canister +## Step 3: Compile and deploy `performance_counters` canister ```sh dfx deploy @@ -90,7 +79,7 @@ URLs: performance_counters: http://127.0.0.1/... ``` -### Step 5: Call `performance_counters` canister `for_update` method +## Step 4: Call `performance_counters` canister `for_update` method ```sh dfx canister call performance_counters for_update @@ -105,7 +94,7 @@ Example output: Note, how the current message execution counter (~6M instructions) is much different from the call context counter (~19M instructions). -### Step 6: Check the Internet Computer replica terminal window for more details +## Step 5: Check the replica terminal window for more details Example replica log output: @@ -123,7 +112,7 @@ By contrast, the call context performance counter (1) is monotonically increasin Also note, that both counters start over for each nested execution (~12K instructions). -### Step 7: Repeat the steps above calling `for_composite_query` method +## Step 6: Repeat the steps above calling `for_composite_query` method ```sh dfx canister call performance_counters for_composite_query diff --git a/rust/periodic_tasks/README.md b/rust/periodic_tasks/README.md index 3e68e1c71..62fe33fc9 100644 --- a/rust/periodic_tasks/README.md +++ b/rust/periodic_tasks/README.md @@ -1,13 +1,5 @@ ---- -keywords: [advanced, rust, periodic, timer, heartbeats] ---- - # Periodic tasks and timers -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/periodic_tasks) - -## Overview - Unlike other blockchains, the Internet Computer can automatically execute canister smart contracts after a specified delay or periodically. There are two ways to schedule an automatic canister execution on the IC: From 17d0ac3b609e0c0cd77f0f16f72e5e62a55de311 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon Date: Thu, 19 Dec 2024 08:57:33 -0600 Subject: [PATCH 04/51] apply codereview --- motoko/encrypted-notes-dapp-vetkd/README.md | 6 +++--- motoko/threshold-schnorr/README.md | 13 +++++++++---- motoko/token_transfer/README.md | 2 +- motoko/token_transfer_from/README.md | 2 +- motoko/vetkd/README.md | 4 ++++ 5 files changed, 18 insertions(+), 9 deletions(-) diff --git a/motoko/encrypted-notes-dapp-vetkd/README.md b/motoko/encrypted-notes-dapp-vetkd/README.md index 1c2ecec80..fa94ca70e 100644 --- a/motoko/encrypted-notes-dapp-vetkd/README.md +++ b/motoko/encrypted-notes-dapp-vetkd/README.md @@ -24,7 +24,7 @@ This example requires an installation of: - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` ## Step 1: Choose which implementation to use by setting a respective environment variable. - + For **Motoko** deployment use: ```sh @@ -50,13 +50,13 @@ _Note_: see [Troubleshooting](#troubleshooting) in case of problems. dfx start --clean ``` -> ![TIP] +> [!TIP] > If you see an error `Failed to set socket of tcp builder to 0.0.0.0:8000`, make sure that the port `8000` is not occupied, e.g., by the previously run Docker command (you might want to stop the Docker daemon whatsoever for this step). ## Step 5: Install a local [Internet Identity (II)](https://wiki.internetcomputer.org/wiki/What_is_Internet_Identity) canister: -> ![TIP] +> [!TIP] > If you have multiple `dfx` identities set up, ensure you are using the identity you intend to use with the `--identity` flag. 1. To install and deploy a canister run: diff --git a/motoko/threshold-schnorr/README.md b/motoko/threshold-schnorr/README.md index f4ae0c23b..6d3d3521e 100644 --- a/motoko/threshold-schnorr/README.md +++ b/motoko/threshold-schnorr/README.md @@ -39,24 +39,29 @@ Begin by opening a terminal window. ## Step 1: Setup the project environment -Navigate into the folder containing the project's files, start a local instance of the Internet Computer and deploy the project with the commands: +Navigate into the folder containing the project's files, start a local instance of the Internet Computer and with the commands: ```bash cd examples/motoko/threshold-schnorr dfx start --background +``` + +#### What this does +- `dfx start --background` starts a local instance of the IC via the IC SDK + +## Step 2: Deploy the canisters + +```bash make deploy ``` To test (includes deploying): ```bash -cd examples/motoko/threshold-schnorr -dfx start --background npm install @noble/curves make test ``` #### What this does -- `dfx start --background` starts a local instance of the IC via the IC SDK - `make deploy` deploys the canister code on the local version of the IC - `npm install @noble/curves` installs a test javascript dependency - `make test` deploys and tests the canister code on the local version of the IC diff --git a/motoko/token_transfer/README.md b/motoko/token_transfer/README.md index 95ad249d8..e22559f42 100644 --- a/motoko/token_transfer/README.md +++ b/motoko/token_transfer/README.md @@ -137,7 +137,7 @@ URLs: ## Step 7: Verify that the ledger canister is healthy and working as expected by using the command -> ![TIP] +> [!TIP] > [Learn more about how to interact with the ICRC-1 ledger](https://internetcomputer.org/docs/current/developer-docs/defi/icrc-1/using-icrc1-ledger#icrc-1-and-icrc-1-extension-endpoints). ````bash diff --git a/motoko/token_transfer_from/README.md b/motoko/token_transfer_from/README.md index 0bc1270f4..ee7e34874 100644 --- a/motoko/token_transfer_from/README.md +++ b/motoko/token_transfer_from/README.md @@ -151,7 +151,7 @@ URLs: ## Step 7: Verify that the ledger canister is healthy and working as expected by using the command -> ![TIP] +> [!TIP] > [Learn more about how to interact with the ICRC-1 ledger](https://internetcomputer.org/docs/current/developer-docs/defi/icrc-1/using-icrc1-ledger#icrc-1-and-icrc-1-extension-endpoints). ````bash diff --git a/motoko/vetkd/README.md b/motoko/vetkd/README.md index a7c5a5be1..764e30862 100644 --- a/motoko/vetkd/README.md +++ b/motoko/vetkd/README.md @@ -11,10 +11,14 @@ Additionally, the repository provides: Because the `ic-vetkd-utils` are not yet published as NPM package at [npmjs.com](https://npmjs.com), a respective package file (`ic-vetkd-utils-0.1.0.tgz`) is included in this repository. +--- + ## Disclaimer The implementation of [the proposed vetKD system API](https://github.com/dfinity/interface-spec/pull/158) used in this example is **unsafe**, e.g., we hard-code a master secret key, rather than using a master secret key that is distributed among sufficiently many Internet Computer nodes through distributed key generation. **Do not use this in production or for sensitive data**! This example is solely provided **for demonstration purposes** to collect feedback on the mentioned vetKD system API. See also the respective disclaimer [in the system API canister implementation](https://github.com/dfinity/examples/blob/master/rust/vetkd/src/system_api/src/lib.rs#L19-L26). +--- + ### Prerequisites This example requires an installation of: From da93e55f620b803f483ede0d286e7d0b12728839 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon Date: Thu, 19 Dec 2024 09:47:05 -0600 Subject: [PATCH 05/51] fix size --- archive/motoko/dip721-nft-container/README.md | 2 +- archive/motoko/hello/README.md | 2 +- archive/motoko/persistent-storage/README.md | 2 +- motoko/counter/README.md | 2 +- motoko/encrypted-notes-dapp-vetkd/README.md | 2 +- motoko/encrypted-notes-dapp/README.md | 20 +++++++------- motoko/hello_cycles/README.md | 6 ++--- motoko/ic-pos/README.md | 8 +++--- motoko/icrc2-swap/README.md | 4 +-- .../internet_identity_integration/README.md | 10 +++---- motoko/life/README.md | 4 +-- motoko/minimal-counter-dapp/README.md | 4 +-- motoko/parallel_calls/README.md | 8 +++--- motoko/pub-sub/README.md | 4 +-- motoko/random_maze/README.md | 4 +-- motoko/superheroes/README.md | 4 +-- motoko/threshold-ecdsa/README.md | 26 +++++++++---------- motoko/threshold-schnorr/README.md | 6 ++--- motoko/token_transfer/README.md | 2 +- motoko/token_transfer_from/README.md | 4 +-- motoko/vetkd/README.md | 4 +-- motoko/whoami/README.md | 2 +- rust/dip721-nft-container/README.md | 2 +- rust/hello/README.md | 2 +- rust/query_stats/README.md | 2 +- 25 files changed, 68 insertions(+), 68 deletions(-) diff --git a/archive/motoko/dip721-nft-container/README.md b/archive/motoko/dip721-nft-container/README.md index 8c64029fd..9f822cb3f 100644 --- a/archive/motoko/dip721-nft-container/README.md +++ b/archive/motoko/dip721-nft-container/README.md @@ -88,7 +88,7 @@ Using this management canister address, we can construct its principal and set t ## NFT sample code tutorial -### Prerequisites +## Prerequisites - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). - [x] Download and install [git.](https://git-scm.com/downloads) diff --git a/archive/motoko/hello/README.md b/archive/motoko/hello/README.md index 60eede1fa..ad70e6fcd 100644 --- a/archive/motoko/hello/README.md +++ b/archive/motoko/hello/README.md @@ -41,7 +41,7 @@ This example demonstrates a dead simple dapp consisting of two canister smart co This example is based on the default project created by running `dfx new hello`. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). - [x] Install `node.js` (to build the web frontend). diff --git a/archive/motoko/persistent-storage/README.md b/archive/motoko/persistent-storage/README.md index 5ba84e19f..bac658057 100644 --- a/archive/motoko/persistent-storage/README.md +++ b/archive/motoko/persistent-storage/README.md @@ -24,7 +24,7 @@ This example covers: ## Installation This example project can be cloned, installed, and deployed locally, for learning and testing purposes. The instructions are based on running the example on either macOS or Linux, but when using WSL2 on Windows, the instructions will be the same. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). diff --git a/motoko/counter/README.md b/motoko/counter/README.md index 3982192df..81cbbb3b6 100644 --- a/motoko/counter/README.md +++ b/motoko/counter/README.md @@ -10,7 +10,7 @@ The application provides an interface that exposes the following methods: - `inc`: increments the value of the counter. - `get`: gets the value of the counter. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). diff --git a/motoko/encrypted-notes-dapp-vetkd/README.md b/motoko/encrypted-notes-dapp-vetkd/README.md index fa94ca70e..c12c50ceb 100644 --- a/motoko/encrypted-notes-dapp-vetkd/README.md +++ b/motoko/encrypted-notes-dapp-vetkd/README.md @@ -16,7 +16,7 @@ This example uses an **insecure** implementation of [the proposed vetKD system A ## Manual local deployment -### Prerequisites +## Prerequisites This example requires an installation of: diff --git a/motoko/encrypted-notes-dapp/README.md b/motoko/encrypted-notes-dapp/README.md index 39340faea..0a9e5bbf8 100644 --- a/motoko/encrypted-notes-dapp/README.md +++ b/motoko/encrypted-notes-dapp/README.md @@ -20,7 +20,7 @@ This is an **example dapp** that demonstrates the potential of building **canist - The frontend re-uses the generated public and private key pair for every identity in the same browser. In a better implementation, this key pair should be unique per principal. - The public/private key pair should not be managed by the web browser at all. [WebAuthn](https://en.wikipedia.org/wiki/WebAuthn) should be used to push the key management to the operating system. -- Integer overflows are possible in the Rust canister, e.g., for `NEXT_NOTE`. +- Integer overflows are possible in the Rust canister, e.g., for `NEXT_NOTE`. - Users may lose their notes if they accidentally clean the browser data (localStorage) while no other device is synced to the dapp. - Lack of key update: Given that the key used to encrypt the notes is never refreshed, the privacy of the data is no longer guaranteed if an attacker learns this key (for instance, by corrupting the local storage in one of the connected devices). @@ -29,8 +29,8 @@ This is an **example dapp** that demonstrates the potential of building **canist You can play around with the [dapp deployed on ICP](https://cvhrw-2yaaa-aaaaj-aaiqa-cai.icp0.io/) and see a quick introduction on [YouTube](https://youtu.be/DZQmtPSxvbs). -We wanted to build an example of a simple (but not too simple) dapp running purely on the IC. This example relies upon the **web-serving** and **storage capabilities** of the IC. We focused on the following two key features for our example dapp: -1. Client-side **end-to-end encryption**. +We wanted to build an example of a simple (but not too simple) dapp running purely on the IC. This example relies upon the **web-serving** and **storage capabilities** of the IC. We focused on the following two key features for our example dapp: +1. Client-side **end-to-end encryption**. 2. **Multi-user** and **multi-device** support. To demonstrate the potential of the IC as a platform for developing such dapps, we implemented this example using two distinct canister development kits (CDKs). The Motoko CDK allows developers to implement actor-based dapps using the [Motoko](https://internetcomputer.org/docs/current/motoko/getting-started/motoko-introduction) language. The Rust CDK allows implementing dapps in [Rust](https://internetcomputer.org/docs/current/developer-docs/backend/rust/). In both cases, canisters are compiled into WebAssembly files that are then deployed onto the IC. @@ -100,7 +100,7 @@ Once authenticated with II: Follow the steps below to deploy this sample project. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). @@ -126,7 +126,7 @@ export BUILD_ENV=motoko **Building the Rust canister requires either the Rust toolchain installed on your system or Docker-backed deployment (see below).** - + ## Step 3: Deploy locally ### Option 1: Docker deployment @@ -139,7 +139,7 @@ export BUILD_ENV=motoko export BUILD_ENV=motoko ``` -- #### Step 3: Run the following Bash script that builds a Docker image, compiles the canister, and deploys this dapp (all inside the Docker instance). +- #### Step 3: Run the following Bash script that builds a Docker image, compiles the canister, and deploys this dapp (all inside the Docker instance). Execution can take a few minutes: @@ -278,11 +278,11 @@ dfx canister --network ic install www --mode=upgrade ## Security considerations and best practices -If you base your application on this example, we recommend you familiarize yourself with and adhere to the [security best practices](https://internetcomputer.org/docs/current/references/security/) for developing on the Internet Computer. This example may not implement all the best practices, see also the [disclaimer](#disclaimer-please-read-carefully) above. +If you base your application on this example, we recommend you familiarize yourself with and adhere to the [security best practices](https://internetcomputer.org/docs/current/references/security/) for developing on the Internet Computer. This example may not implement all the best practices, see also the [disclaimer](#disclaimer-please-read-carefully) above. -For example, the following aspects are particularly relevant for this app: +For example, the following aspects are particularly relevant for this app: * [Make sure any action that only a specific user should be able to do requires authentication](https://internetcomputer.org/docs/current/developer-docs/security/security-best-practices/overview), since a user should only be able to manage their own notes. -* [Protect key material against XSS using Web Crypto API](https://internetcomputer.org/docs/current/references/security/web-app-development-security-best-practices#crypto-protect-key-material-against-xss-using-web-crypto-api), since this app stores private keys in the browser. +* [Protect key material against XSS using Web Crypto API](https://internetcomputer.org/docs/current/references/security/web-app-development-security-best-practices#crypto-protect-key-material-against-xss-using-web-crypto-api), since this app stores private keys in the browser. * [Use secure cryptographic schemes](https://internetcomputer.org/docs/current/references/security/general-security-best-practices#use-secure-cryptographic-schemes), since notes are being encrypted. ## User interaction with "Encrypted Notes" dapp @@ -476,7 +476,7 @@ frontend www canister (an "asset" canister) is the way we describe a set of file `dependencies`: an array of whatever canisters are being used to serve your app, to ensure that `dfx` builds and deploys them before your app. `frontend: { entrypoint: ""}`: This set of keys tells `dfx` to build it as a frontend canister, and entrypoint is wherever your app entrypoint winds up residing at the end of an npm build `source`: where the rest of your app resides at the end of npm build -`type`: "assets" for an assets or static canister. +`type`: "assets" for an assets or static canister. **Binary targets**: You can also just deploy arbitrary binary targets as long as they're wasm binaries. For that, use the keys: diff --git a/motoko/hello_cycles/README.md b/motoko/hello_cycles/README.md index 430e2fadc..36c997f42 100644 --- a/motoko/hello_cycles/README.md +++ b/motoko/hello_cycles/README.md @@ -16,9 +16,9 @@ This example consists of the following functions (see `src/hello_cycles/main.mo` The wallet's `wallet_receive` return type differs from hello_cycle's `wallet_receive`. ::: -This is a Motoko example that does not currently have a Rust variant. +This is a Motoko example that does not currently have a Rust variant. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). @@ -124,7 +124,7 @@ The amount is only increased by 10_000_000 because the implementation of `wallet dfx canister call hello_cycles transfer "(func \"$(dfx identity get-wallet)\".\"wallet_receive\", 5000000)" ``` -Output: +Output: ```bash (record { refunded = 0 : nat }) diff --git a/motoko/ic-pos/README.md b/motoko/ic-pos/README.md index aba1d5dc7..18d707232 100644 --- a/motoko/ic-pos/README.md +++ b/motoko/ic-pos/README.md @@ -50,7 +50,7 @@ The frontend interacts with the following IC canisters: - `ckbtc index` - to fetch transaction history. - `internet identity` - to authenticate users. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). @@ -171,7 +171,7 @@ dfx canister call icpos setCourierApiKey "pk_prod_..." ### Step 8: Build and run the frontend -Run npm to install dependencies and start a development version of the frontend. +Run npm to install dependencies and start a development version of the frontend. ```bash pnpm install @@ -203,7 +203,7 @@ dfx canister call icrc1_ledger icrc1_transfer ' ### Step 11: Create the second store -Log in to the frontend using **a new Internet Identity using another web browser**. Give this store a name as well and copy the store principal like in the previous step. +Log in to the frontend using **a new Internet Identity using another web browser**. Give this store a name as well and copy the store principal like in the previous step. Now, go back to the first browser/store, navigate to the `Send` page, and transfer some tokens to the second store. @@ -213,7 +213,7 @@ If everything is working, you should see a notification in the second store. ## Possible improvements -- Show more information about transactions. +- Show more information about transactions. - A transaction detail page. - Pagination, currently only the first 5 transactions are shown. - Show a confirmation dialog after the user clicks on the `Send` button. diff --git a/motoko/icrc2-swap/README.md b/motoko/icrc2-swap/README.md index 6c4fd1efd..cc667ac81 100644 --- a/motoko/icrc2-swap/README.md +++ b/motoko/icrc2-swap/README.md @@ -19,7 +19,7 @@ different from other synchronous blockchains. ## Local deployment -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). @@ -265,7 +265,7 @@ the token balances. The example comes with a test suite to demonstrate the basic functionality. It shows how to use this repo from a Javascript client. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). diff --git a/motoko/internet_identity_integration/README.md b/motoko/internet_identity_integration/README.md index 8626b1754..7e1f51456 100644 --- a/motoko/internet_identity_integration/README.md +++ b/motoko/internet_identity_integration/README.md @@ -1,4 +1,4 @@ -# Internet Identity integration +# Internet Identity integration This tutorial shows how to integrate Internet Identity into a dapp front-end and make use of the user identity in the backend. It builds on the "greet" dapp that is generated by running `dfx new`. If you are unfamiliar with `dfx new` and the generated application, please have a look at [this](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx) guide first. @@ -11,12 +11,12 @@ This tutorial will explain all the steps required to integrate the default start This is a Motoko example that does not currently have a Rust variant. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -- [x] Download and install the `@dfinity/auth-client` package with the command `npm install @dfinity/auth-client`. +- [x] Download and install the `@dfinity/auth-client` package with the command `npm install @dfinity/auth-client`. - [x] Chrome or Firefox browser (other browsers also work, but may need a slightly different webpack configuration, see the note on [step 4 below](#step-4-make-the-internet-identity-url-available-in-the-build-process)) Begin by opening a terminal window. @@ -338,7 +338,7 @@ loginButton.onclick = async (e) => { }); return false; -};% +};% ``` ## Step 8: Modify the backend @@ -378,7 +378,7 @@ URLs: ## Step 10: Test the application -Open the `greet_frontend` URL in a web browser. +Open the `greet_frontend` URL in a web browser. You should be able to observe the following behavior: diff --git a/motoko/life/README.md b/motoko/life/README.md index 00e9aa435..98836077e 100644 --- a/motoko/life/README.md +++ b/motoko/life/README.md @@ -12,9 +12,9 @@ Directories `versions/v1` and `versions/v2` contain sequential upgrades to src u To make upgrades apparent, each version uses a different digit to display live cells (0,1,2). -This is a Motoko example that does not currently have a Rust variant. +This is a Motoko example that does not currently have a Rust variant. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). diff --git a/motoko/minimal-counter-dapp/README.md b/motoko/minimal-counter-dapp/README.md index 43239413b..7d2394cca 100644 --- a/motoko/minimal-counter-dapp/README.md +++ b/motoko/minimal-counter-dapp/README.md @@ -15,7 +15,7 @@ This example covers: - Deploy the canister smart contract locally. - Test backend with Candid UI and command line using `dfx`, and test frontend in browser. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). @@ -123,7 +123,7 @@ public func reset() : async Nat { ``` ### Candid interface -The Candid interface is automatically created, and it has a convenient UI, which provides an easy, user-friendly way to test the backend. Learn how to access the Candid UI in the **Testing** section below. +The Candid interface is automatically created, and it has a convenient UI, which provides an easy, user-friendly way to test the backend. Learn how to access the Candid UI in the **Testing** section below. ### Frontend The default project installed with `dfx new project_name` implements the logic that serves the frontend in the `src/minimal_dapp_frontend/src/App.js` file, and most of the HTML is carried over from the default project. diff --git a/motoko/parallel_calls/README.md b/motoko/parallel_calls/README.md index 51e2a5858..3232ffdca 100644 --- a/motoko/parallel_calls/README.md +++ b/motoko/parallel_calls/README.md @@ -10,7 +10,7 @@ The sample code revolves around two simple canisters, `caller` and `callee`. `Ca The callee exposes a simple `ping` endpoint that takes no parameters and returns nothing. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). @@ -54,7 +54,7 @@ This should output: (100 : nat64) ``` -And the other endpoint: +And the other endpoint: ```bash dfx canister call caller parallel_calls 100 @@ -96,9 +96,9 @@ Lastly, the parallel calls here complete sooner -- because most of them fail! ## Step 5: Multi-subnet setting -Parallel calls are a lot more useful in multi-subnet settings. We can create such a setting locally using Pocket IC. +Parallel calls are a lot more useful in multi-subnet settings. We can create such a setting locally using Pocket IC. -First, follow the [installation instructions](https://github.com/dfinity/pocketic) to install `pocket-ic` in the `parallel_calls` directory. +First, follow the [installation instructions](https://github.com/dfinity/pocketic) to install `pocket-ic` in the `parallel_calls` directory. Then, run the pre-made test, which now installs the `caller` and `callee` canisters on different subnets, and then runs 90 calls sequentially/in parallel. diff --git a/motoko/pub-sub/README.md b/motoko/pub-sub/README.md index 683e88581..68254f660 100644 --- a/motoko/pub-sub/README.md +++ b/motoko/pub-sub/README.md @@ -4,7 +4,7 @@ This sample project demonstrates how functions may be passed as arguments of int A common problem in both distributed and decentralized systems is keeping separate services (or canisters) synchronized with one another. While there are many potential solutions to this problem, a popular one is the publisher/subscriber pattern or "PubSub". PubSub is an especially valuable pattern on the Internet Computer as its primary drawback, message delivery failures, does not apply. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). @@ -55,7 +55,7 @@ The output should resemble the following: If you base your application on this example, we recommend you familiarize yourself with and adhere to the [security best practices](https://internetcomputer.org/docs/current/references/security/) for developing on the Internet Computer. This example may not implement all the best practices. -For example, the following aspects are particularly relevant for this app, since it makes inter-canister calls: +For example, the following aspects are particularly relevant for this app, since it makes inter-canister calls: * [Be aware that state may change during inter-canister calls.](https://internetcomputer.org/docs/current/developer-docs/security/security-best-practices/overview) * [Only make inter-canister calls to trustworthy canisters.](https://internetcomputer.org/docs/current/developer-docs/security/security-best-practices/overview) * [Don’t panic after await and don’t lock shared resources across await boundaries.](https://internetcomputer.org/docs/current/developer-docs/security/security-best-practices/overview) diff --git a/motoko/random_maze/README.md b/motoko/random_maze/README.md index 65714318b..2ca9878d6 100644 --- a/motoko/random_maze/README.md +++ b/motoko/random_maze/README.md @@ -16,9 +16,9 @@ This actor uses Motoko's random library to generate a cryptographically random m The function `generate` calls library function `Random.blob()` asynchronously to obtain 256 bits of raw entropy (256 random bits as 32 bytes) from the Internet Computer. It makes these calls on demand as it is constructing a maze. The bits of these blobs are consumed to generate samples from a variety of discrete distributions using some of the other classes and functions of library Random.mo. -This is a Motoko example that does not currently have a Rust variant. +This is a Motoko example that does not currently have a Rust variant. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). diff --git a/motoko/superheroes/README.md b/motoko/superheroes/README.md index 3ea4b6122..2440a8f9f 100644 --- a/motoko/superheroes/README.md +++ b/motoko/superheroes/README.md @@ -2,9 +2,9 @@ This example demonstrates how to build a CRUD application on ICP using Motoko and React. -This is a Motoko example that does not currently have a Rust variant. +This is a Motoko example that does not currently have a Rust variant. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). diff --git a/motoko/threshold-ecdsa/README.md b/motoko/threshold-ecdsa/README.md index f72dd7aae..f83737802 100644 --- a/motoko/threshold-ecdsa/README.md +++ b/motoko/threshold-ecdsa/README.md @@ -1,13 +1,13 @@ # Threshold ECDSA sample -We present a minimal example canister smart contract for showcasing the [threshold ECDSA](https://internetcomputer.org/docs/current/developer-docs/integrations/t-ecdsa) API. +We present a minimal example canister smart contract for showcasing the [threshold ECDSA](https://internetcomputer.org/docs/current/developer-docs/integrations/t-ecdsa) API. -The example canister is a signing oracle that creates ECDSA signatures with keys derived from an input string. +The example canister is a signing oracle that creates ECDSA signatures with keys derived from an input string. More specifically: - The sample canister receives a request that provides a message. -- The sample canister hashes the message and uses the key derivation string for the derivation path. +- The sample canister hashes the message and uses the key derivation string for the derivation path. - The sample canister uses the above to request a signature from the threshold ECDSA [subnet](https://wiki.internetcomputer.org/wiki/Subnet_blockchain) (the threshold ECDSA is a subnet specializing in generating threshold ECDSA signatures). This tutorial gives a complete overview of the development, starting with downloading the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/index.md), up to the deployment and trying out the code on the IC mainnet. @@ -19,7 +19,7 @@ This tutorial gives a complete overview of the development, starting with downlo Sample code for `threshold-ecdsa` is provided in the [examples repository](https://github.com/dfinity/examples), under either [`/motoko`](https://github.com/dfinity/examples/tree/master/motoko/threshold-ecdsa) or [`/rust`](https://github.com/dfinity/examples/tree/master/rust/threshold-ecdsa) sub-directories. It requires at least [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/index.md) version 0.11.0 for local development. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). @@ -131,21 +131,21 @@ In the example below, the method returns `03c22bef676644dba524d4a24132ea8463221a "Ok": { "public_key_hex": "03c22bef676644dba524d4a24132ea8463221a55540a27fc86d690fda8e688e31a" - } + } } ``` ### Code walkthrough -Open the file `main.mo`, which will show the following Motoko code that demonstrates how to obtain an ECDSA public key. +Open the file `main.mo`, which will show the following Motoko code that demonstrates how to obtain an ECDSA public key. ```motoko - //declare "ic" to be the management canister, which is evoked by `actor("aaaaa-aa")`. This is how we will obtain an ECDSA public key + //declare "ic" to be the management canister, which is evoked by `actor("aaaaa-aa")`. This is how we will obtain an ECDSA public key let ic : IC = actor("aaaaa-aa"); public shared (msg) func public_key() : async { #Ok : { public_key: Blob }; #Err : Text } { let caller = Principal.toBlob(msg.caller); - + try { //request the management canister to compute an ECDSA public key @@ -157,19 +157,19 @@ Open the file `main.mo`, which will show the following Motoko code that demonstr //this code uses the mainnet test key key_id = { curve = #secp256k1; name = "test_key_1" }; }); - + #Ok({ public_key }) - + } catch (err) { - + #Err(Error.message(err)) - + } }; ``` -In the code above, the canister calls the `ecdsa_public_key` method of the [IC management canister](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-management-canister) (`aaaaa-aa`). +In the code above, the canister calls the `ecdsa_public_key` method of the [IC management canister](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-management-canister) (`aaaaa-aa`). **The [IC management canister](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-management-canister) is just a facade; it does not exist as a canister (with isolated state, Wasm code, etc.). It is an ergonomic way for canisters to call the system API of the IC (as if it were a single canister). In the code below, we use the management canister to create an ECDSA public key. `let ic : IC = actor("aaaaa-aa")` declares the IC management canister in the code above.** diff --git a/motoko/threshold-schnorr/README.md b/motoko/threshold-schnorr/README.md index 6d3d3521e..341c50734 100644 --- a/motoko/threshold-schnorr/README.md +++ b/motoko/threshold-schnorr/README.md @@ -29,7 +29,7 @@ version available in the same repo and follows the same commands for deploying. Sample code for `threshold-schnorr-example` is provided in the [examples repository](https://github.com/dfinity/examples), under either [`/motoko`](https://github.com/dfinity/examples/tree/master/motoko/threshold-schnorr) or [`/rust`](https://github.com/dfinity/examples/tree/master/rust/threshold-schnorr) sub-directories. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). @@ -156,7 +156,7 @@ Ed25519 public key. ### Code walkthrough Open the file `lib.rs`, which will show the following Motoko code that -demonstrates how to obtain a Schnorr public key. +demonstrates how to obtain a Schnorr public key. ```motoko public shared ({ caller }) func public_key(algorithm_arg : SchnorrAlgotirhm) : async { @@ -176,7 +176,7 @@ demonstrates how to obtain a Schnorr public key. }; ``` -In the code above, the canister calls the `schnorr_public_key` method of the [IC management canister](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-management-canister) (`aaaaa-aa`). +In the code above, the canister calls the `schnorr_public_key` method of the [IC management canister](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-management-canister) (`aaaaa-aa`). **The [IC management diff --git a/motoko/token_transfer/README.md b/motoko/token_transfer/README.md index e22559f42..87076dadc 100644 --- a/motoko/token_transfer/README.md +++ b/motoko/token_transfer/README.md @@ -8,7 +8,7 @@ The sample code revolves around one core transfer function which takes as input This sample will use the Motoko variant. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). diff --git a/motoko/token_transfer_from/README.md b/motoko/token_transfer_from/README.md index ee7e34874..1f455b918 100644 --- a/motoko/token_transfer_from/README.md +++ b/motoko/token_transfer_from/README.md @@ -8,7 +8,7 @@ The sample code revolves around one core transfer function which takes as input This sample will use the Rust variant. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). @@ -240,7 +240,7 @@ dfx deploy token_transfer_from_backend ## Step 10: Approve the canister to transfer funds on behalf of the user -:::info +:::info Make sure that you are using the default `dfx` account that we minted tokens to in step 5 for the following steps. diff --git a/motoko/vetkd/README.md b/motoko/vetkd/README.md index 764e30862..983ecc6d1 100644 --- a/motoko/vetkd/README.md +++ b/motoko/vetkd/README.md @@ -8,7 +8,7 @@ Additionally, the repository provides: * An example frontend (`src/app_frontend_js`) that uses the backend from Javascript in the browser. The frontend uses the [ic-vetkd-utils](https://github.com/dfinity/ic/tree/master/packages/ic-vetkd-utils) to create a transport key pair that is used to obtain a verifiably encrypted key from the system API, to decrypt this key, and to derive a symmetric key to be used for AES encryption/decryption. - + Because the `ic-vetkd-utils` are not yet published as NPM package at [npmjs.com](https://npmjs.com), a respective package file (`ic-vetkd-utils-0.1.0.tgz`) is included in this repository. --- @@ -19,7 +19,7 @@ The implementation of [the proposed vetKD system API](https://github.com/dfinity --- -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). diff --git a/motoko/whoami/README.md b/motoko/whoami/README.md index 1824097ff..268067e7f 100644 --- a/motoko/whoami/README.md +++ b/motoko/whoami/README.md @@ -2,7 +2,7 @@ This example demonstrates how a canister can identify its caller and itself. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). diff --git a/rust/dip721-nft-container/README.md b/rust/dip721-nft-container/README.md index ed4157991..17fd4f628 100644 --- a/rust/dip721-nft-container/README.md +++ b/rust/dip721-nft-container/README.md @@ -92,7 +92,7 @@ A running instance of the Rust canister for demonstration purposes is available The interface is meant to be programmatic, but the Rust version additionally contains HTTP functionality so you can view a metadata file at `//`. It contains six NFTs, so you can look at items from `/0/0` to `/5/0`. -### Prerequisites +## Prerequisites - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). - [x] Download and install [git.](https://git-scm.com/downloads) diff --git a/rust/hello/README.md b/rust/hello/README.md index 5be675357..6a7219962 100644 --- a/rust/hello/README.md +++ b/rust/hello/README.md @@ -43,7 +43,7 @@ This example is based on the default project created by running `dfx new hello`. This example is based on the default project created by running `dfx new --type=rust hello`. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). - [x] Install `node.js` (to build the web frontend). diff --git a/rust/query_stats/README.md b/rust/query_stats/README.md index cdec34a6d..d50b97587 100644 --- a/rust/query_stats/README.md +++ b/rust/query_stats/README.md @@ -27,7 +27,7 @@ The `load` function just returns a timestamp. It just exists such that there is a query endpoint to call. The `get_query_stats` is the function that queries the status endpoint and returns the collected query statistics. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). - [x] Install `node.js` (to build the web frontend). From bda355ceca475995174ffb203492724c7d4ecb01 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Thu, 19 Dec 2024 09:49:06 -0600 Subject: [PATCH 06/51] Apply suggestions from code review --- rust/dip721-nft-container/README.md | 2 +- rust/hello/README.md | 2 +- rust/query_stats/README.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rust/dip721-nft-container/README.md b/rust/dip721-nft-container/README.md index 17fd4f628..3759f2a7b 100644 --- a/rust/dip721-nft-container/README.md +++ b/rust/dip721-nft-container/README.md @@ -92,7 +92,7 @@ A running instance of the Rust canister for demonstration purposes is available The interface is meant to be programmatic, but the Rust version additionally contains HTTP functionality so you can view a metadata file at `//`. It contains six NFTs, so you can look at items from `/0/0` to `/5/0`. -## Prerequisites +### Prerequisites - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). - [x] Download and install [git.](https://git-scm.com/downloads) diff --git a/rust/hello/README.md b/rust/hello/README.md index 6a7219962..5be675357 100644 --- a/rust/hello/README.md +++ b/rust/hello/README.md @@ -43,7 +43,7 @@ This example is based on the default project created by running `dfx new hello`. This example is based on the default project created by running `dfx new --type=rust hello`. -## Prerequisites +### Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). - [x] Install `node.js` (to build the web frontend). diff --git a/rust/query_stats/README.md b/rust/query_stats/README.md index d50b97587..cdec34a6d 100644 --- a/rust/query_stats/README.md +++ b/rust/query_stats/README.md @@ -27,7 +27,7 @@ The `load` function just returns a timestamp. It just exists such that there is a query endpoint to call. The `get_query_stats` is the function that queries the status endpoint and returns the collected query statistics. -## Prerequisites +### Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). - [x] Install `node.js` (to build the web frontend). From 4fef3391a2f9a2a2051c95059cae2fa00931e373 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Thu, 19 Dec 2024 09:49:31 -0600 Subject: [PATCH 07/51] Update rust/dip721-nft-container/README.md --- rust/dip721-nft-container/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/dip721-nft-container/README.md b/rust/dip721-nft-container/README.md index 3759f2a7b..ed4157991 100644 --- a/rust/dip721-nft-container/README.md +++ b/rust/dip721-nft-container/README.md @@ -92,7 +92,7 @@ A running instance of the Rust canister for demonstration purposes is available The interface is meant to be programmatic, but the Rust version additionally contains HTTP functionality so you can view a metadata file at `//`. It contains six NFTs, so you can look at items from `/0/0` to `/5/0`. -### Prerequisites +### Prerequisites - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). - [x] Download and install [git.](https://git-scm.com/downloads) From 4e542d1df29604bb79e064b8eefc97e2bd5c69a2 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Thu, 19 Dec 2024 13:57:38 -0600 Subject: [PATCH 08/51] Update motoko/send_http_post/README.md --- motoko/send_http_post/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/motoko/send_http_post/README.md b/motoko/send_http_post/README.md index bfa2b865c..1d4868f58 100644 --- a/motoko/send_http_post/README.md +++ b/motoko/send_http_post/README.md @@ -8,7 +8,7 @@ If you want to start working on your project right away, you might want to try t ```bash git clone https://github.com/dfinity/examples -cd examples/motoko/send_http_post_motoko +cd examples/motoko/send_http_post dfx start --background dfx deploy ``` From 5091d55e84e18c3bbb52515d796545ff9a3ec6f2 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Thu, 19 Dec 2024 14:20:18 -0600 Subject: [PATCH 09/51] Update README.md --- motoko/threshold-ecdsa/README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/motoko/threshold-ecdsa/README.md b/motoko/threshold-ecdsa/README.md index f83737802..efbc25255 100644 --- a/motoko/threshold-ecdsa/README.md +++ b/motoko/threshold-ecdsa/README.md @@ -10,19 +10,17 @@ More specifically: - The sample canister hashes the message and uses the key derivation string for the derivation path. - The sample canister uses the above to request a signature from the threshold ECDSA [subnet](https://wiki.internetcomputer.org/wiki/Subnet_blockchain) (the threshold ECDSA is a subnet specializing in generating threshold ECDSA signatures). -This tutorial gives a complete overview of the development, starting with downloading the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/index.md), up to the deployment and trying out the code on the IC mainnet. +This tutorial gives a complete overview of the development, starting with downloading the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install), up to the deployment and trying out the code on the IC mainnet. > [!TIP] > This walkthrough focuses on the version of the sample canister code written in [Motoko](https://internetcomputer.org/docs/current/developer-docs/backend/motoko/index.md) programming language, but no specific knowledge of Motoko is needed to follow along. There is also a [Rust](https://github.com/dfinity/examples/tree/master/rust/threshold-ecdsa) version available in the same repo and follows the same commands for deploying. ## Getting started -Sample code for `threshold-ecdsa` is provided in the [examples repository](https://github.com/dfinity/examples), under either [`/motoko`](https://github.com/dfinity/examples/tree/master/motoko/threshold-ecdsa) or [`/rust`](https://github.com/dfinity/examples/tree/master/rust/threshold-ecdsa) sub-directories. It requires at least [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/index.md) version 0.11.0 for local development. - ## Prerequisites This example requires an installation of: -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install) v0.11.0 or newer. - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` Begin by opening a terminal window. From 8e6f6827293f02c60bbb88e1c73f08a9385d771d Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Thu, 19 Dec 2024 14:28:55 -0600 Subject: [PATCH 10/51] Update README.md --- motoko/threshold-ecdsa/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/motoko/threshold-ecdsa/README.md b/motoko/threshold-ecdsa/README.md index efbc25255..724caf20e 100644 --- a/motoko/threshold-ecdsa/README.md +++ b/motoko/threshold-ecdsa/README.md @@ -15,8 +15,6 @@ This tutorial gives a complete overview of the development, starting with downlo > [!TIP] > This walkthrough focuses on the version of the sample canister code written in [Motoko](https://internetcomputer.org/docs/current/developer-docs/backend/motoko/index.md) programming language, but no specific knowledge of Motoko is needed to follow along. There is also a [Rust](https://github.com/dfinity/examples/tree/master/rust/threshold-ecdsa) version available in the same repo and follows the same commands for deploying. -## Getting started - ## Prerequisites This example requires an installation of: From 9d24fde24376b6863e28f51ae9c40123876e0754 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Thu, 19 Dec 2024 14:48:35 -0600 Subject: [PATCH 11/51] Update README.md --- motoko/threshold-schnorr/README.md | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/motoko/threshold-schnorr/README.md b/motoko/threshold-schnorr/README.md index 341c50734..f7697451a 100644 --- a/motoko/threshold-schnorr/README.md +++ b/motoko/threshold-schnorr/README.md @@ -1,9 +1,6 @@ # Threshold Schnorr -We present a minimal example canister smart contract for showcasing the -[threshold -Schnorr](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-sign_with_schnorr) -API. +We present a minimal example canister smart contract for showcasing the [threshold Schnorr](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-sign_with_schnorr) API. The example canister is a signing oracle that creates Schnorr signatures with keys derived based on the canister ID and the chosen algorithm, either BIP340 or @@ -18,21 +15,15 @@ More specifically: (the threshold Schnorr subnet is a subnet generating threshold Schnorr signatures). -This tutorial gives a complete overview of the development, starting with downloading [`dfx`](https://internetcomputer.org/docs/current/developer-docs/setup/index.md), up to the deployment and trying out the code on the mainnet. - This walkthrough focuses on the version of the sample canister code written in Motoko programming language. There is also a [Rust](https://github.com/dfinity/examples/tree/master/rust/threshold-schnorr) version available in the same repo and follows the same commands for deploying. -## Getting started - -Sample code for `threshold-schnorr-example` is provided in the [examples repository](https://github.com/dfinity/examples), under either [`/motoko`](https://github.com/dfinity/examples/tree/master/motoko/threshold-schnorr) or [`/rust`](https://github.com/dfinity/examples/tree/master/rust/threshold-schnorr) sub-directories. - ## Prerequisites This example requires an installation of: -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` Begin by opening a terminal window. From 323c7689ca1478a48b11cadf50c56d566a12b230 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon Date: Thu, 19 Dec 2024 15:39:54 -0600 Subject: [PATCH 12/51] Update rust readmes --- rust/basic_bitcoin/README.md | 10 +- rust/basic_dao/README.md | 2 +- rust/basic_ethereum/README.md | 2 +- rust/canister-snapshots/README.md | 2 +- rust/canister_logs/README.md | 2 +- rust/composite_query/README.md | 2 +- rust/counter/README.md | 2 +- rust/dip721-nft-container/README.md | 2 +- rust/face-recognition/README.md | 2 +- rust/hello/README.md | 2 +- rust/icp_transfer/README.md | 2 +- rust/nft-wallet/README.md | 2 +- rust/parallel_calls/README.md | 2 +- rust/performance_counters/README.md | 5 +- rust/periodic_tasks/README.md | 75 ++++----- rust/pub-sub/README.md | 29 ++-- rust/qrcode/README.md | 21 +-- rust/query_stats/README.md | 37 ++--- rust/send_http_get/README.md | 18 +-- rust/send_http_post/README.md | 22 +-- rust/simd/README.md | 59 ++----- rust/threshold-ecdsa/README.md | 158 +++++-------------- rust/threshold-schnorr/README.md | 230 ++++++++-------------------- rust/token_transfer/README.md | 76 ++++----- rust/token_transfer_from/README.md | 78 ++++------ rust/vetkd/README.md | 34 ++-- rust/x509/README.md | 34 ++-- 27 files changed, 293 insertions(+), 617 deletions(-) diff --git a/rust/basic_bitcoin/README.md b/rust/basic_bitcoin/README.md index 6341aa5ea..53eab4760 100644 --- a/rust/basic_bitcoin/README.md +++ b/rust/basic_bitcoin/README.md @@ -1,4 +1,4 @@ -# Basic Bitcoin +# Basic Bitcoin This tutorial will walk you through how to deploy a sample [canister smart contract](https://internetcomputer.org/docs/current/developer-docs/multi-chain/bitcoin/overview) **that can send and receive Bitcoin** on the Internet Computer. @@ -14,7 +14,7 @@ of the Internet Computer. For a deeper understanding of the ICP < > BTC integration, see the [Bitcoin integration documentation](https://wiki.internetcomputer.org/wiki/Bitcoin_Integration). -### Prerequisites +## Prerequisites * [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). @@ -111,7 +111,7 @@ from three types of addresses: key. This precaution is to prevent attacks that can occur when creating taproot multisigner addresses using specific multisignature schemes. However, the Schnorr API of the internet computer does not support Schnorr - multisignatures. + multisignatures. 3. A [P2TR address](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki) where the funds can be spent using the provided public key with the script @@ -209,7 +209,7 @@ reflected in your current balance. ## Step 6: Retrieving block headers -You can also get a range of Bitcoin block headers by using the `get_block_headers` +You can also get a range of Bitcoin block headers by using the `get_block_headers` endpoint on your canister. In the Candid UI, write the desired start height and optionally end height, and click on "Call": @@ -233,7 +233,7 @@ In this tutorial, you were able to: * Connect the canister to the Bitcoin testnet. * Send the canister some testnet BTC. * Check the testnet BTC balance of the canister. -* Use the canister to send testnet BTC to another testnet BTC address. +* Use the canister to send testnet BTC to another testnet BTC address. This example is extensively documented in the following tutorials: diff --git a/rust/basic_dao/README.md b/rust/basic_dao/README.md index 21a8e403b..c374649e9 100644 --- a/rust/basic_dao/README.md +++ b/rust/basic_dao/README.md @@ -10,7 +10,7 @@ Certain system parameters, like the number of `Yes` votes needed to pass a propo View the [canister service definition](https://github.com/dfinity/examples/blob/master/rust/basic_dao/src/basic_dao/src/basic_dao.did) for more details. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] The Rust toolchain (e.g. cargo). diff --git a/rust/basic_ethereum/README.md b/rust/basic_ethereum/README.md index 0297369ca..9ac78f9e6 100644 --- a/rust/basic_ethereum/README.md +++ b/rust/basic_ethereum/README.md @@ -14,7 +14,7 @@ features of the Internet Computer. For a deeper understanding of the ICP < > ETH integration, see the [Ethereum integration overview](https://internetcomputer.org/docs/current/developer-docs/multi-chain/ethereum/overview). -### Prerequisites +## Prerequisites - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). diff --git a/rust/canister-snapshots/README.md b/rust/canister-snapshots/README.md index 2b222378b..d57b2c83c 100644 --- a/rust/canister-snapshots/README.md +++ b/rust/canister-snapshots/README.md @@ -6,7 +6,7 @@ The `remove_spam` canister method intentionally includes a bug to simulate data The example outlines the steps to install the canister, create a snapshot, and subsequently restore the data after the simulated data loss. -### Prerequisites +## Prerequisites This example requires an installation of: diff --git a/rust/canister_logs/README.md b/rust/canister_logs/README.md index 38f0a52ae..ad5c3ca0b 100644 --- a/rust/canister_logs/README.md +++ b/rust/canister_logs/README.md @@ -1,6 +1,6 @@ # Canister logs -### Prerequisites +## Prerequisites - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. diff --git a/rust/composite_query/README.md b/rust/composite_query/README.md index 82c6b267b..1de116005 100644 --- a/rust/composite_query/README.md +++ b/rust/composite_query/README.md @@ -1,6 +1,6 @@ # Composite queries -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). diff --git a/rust/counter/README.md b/rust/counter/README.md index 2f2ab37b6..de2a5216a 100644 --- a/rust/counter/README.md +++ b/rust/counter/README.md @@ -2,7 +2,7 @@ This example demonstrates a counter application. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/). diff --git a/rust/dip721-nft-container/README.md b/rust/dip721-nft-container/README.md index 016d35ffa..38c3dad98 100644 --- a/rust/dip721-nft-container/README.md +++ b/rust/dip721-nft-container/README.md @@ -86,7 +86,7 @@ A running instance of the Rust canister for demonstration purposes is available The interface is meant to be programmatic, but the Rust version additionally contains HTTP functionality so you can view a metadata file at `//`. It contains six NFTs, so you can look at items from `/0/0` to `/5/0`. -### Prerequisites +## Prerequisites - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` diff --git a/rust/face-recognition/README.md b/rust/face-recognition/README.md index 17bc0b97c..bf6ea0903 100644 --- a/rust/face-recognition/README.md +++ b/rust/face-recognition/README.md @@ -49,7 +49,7 @@ torch.onnx.export(resnet, input, "face-recognition.onnx", verbose=False, opset_v - #### Step 4: This should produce `face-recognition.onnx`. Copy the file to the root of this repository. -### Prerequisites +## Prerequisites - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. diff --git a/rust/hello/README.md b/rust/hello/README.md index b093d864a..c3937ed5b 100644 --- a/rust/hello/README.md +++ b/rust/hello/README.md @@ -36,7 +36,7 @@ This example is based on the default project created by running `dfx new hello`. This example is based on the default project created by running `dfx new --type=rust hello`. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). diff --git a/rust/icp_transfer/README.md b/rust/icp_transfer/README.md index f4dbe96bd..429d4fbee 100644 --- a/rust/icp_transfer/README.md +++ b/rust/icp_transfer/README.md @@ -13,7 +13,7 @@ The sample code revolves around one core transfer function which takes as input This sample will use the Rust variant. -### Prerequisites +## Prerequisites - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. diff --git a/rust/nft-wallet/README.md b/rust/nft-wallet/README.md index 23652a33a..12bf84040 100644 --- a/rust/nft-wallet/README.md +++ b/rust/nft-wallet/README.md @@ -2,7 +2,7 @@ This is an NFT wallet example dapp that utilizes minted NFTs from the Rust dip721-nft-container. Among some of its essential features, the wallet can register NFTs, transfer out NFTs, and check how many NFTs it contains. This dapp includes a frontend UI for interaction. -### Prerequisites +## Prerequisites - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. diff --git a/rust/parallel_calls/README.md b/rust/parallel_calls/README.md index 95db32030..085d8d322 100644 --- a/rust/parallel_calls/README.md +++ b/rust/parallel_calls/README.md @@ -10,7 +10,7 @@ The sample code revolves around two simple canisters, `caller` and `callee`. `Ca The callee exposes a simple `ping` endpoint that takes no parameters and returns nothing. -### Prerequisites +## Prerequisites - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. diff --git a/rust/performance_counters/README.md b/rust/performance_counters/README.md index 218fab4b6..24de25f87 100644 --- a/rust/performance_counters/README.md +++ b/rust/performance_counters/README.md @@ -31,10 +31,7 @@ In the future, ICP might expose more performance counters. ## Prerequisites -## Prerequisites - -- [x] Install the [IC - SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` ## Step 1: Setup project environment diff --git a/rust/periodic_tasks/README.md b/rust/periodic_tasks/README.md index 62fe33fc9..bd7eeb22c 100644 --- a/rust/periodic_tasks/README.md +++ b/rust/periodic_tasks/README.md @@ -14,21 +14,17 @@ The example consists of two canisters named `heartbeat` and `timer`, both implem ## Prerequisites This example requires an installation of: -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -### Example 1: +## Example 1: heartbeats and timers -- #### Step 1: Begin by opening a terminal window and navigating into the project's directory. +- ### Step 1: Setup project environment -```sh -cd examples/rust/periodic_tasks -``` - -- #### Step 2: Start a clean local Internet Computer replica and a web server: +Navigate into the folder containing the project's files and start a local instance of the replica with the command: ```sh -dfx stop +cd examples/rust/periodic_tasks dfx start --clean ``` @@ -37,18 +33,18 @@ This terminal will stay blocked, printing log messages, until the `Ctrl+C` is pr Example output: ```sh -% dfx stop && dfx start --clean +dfx start --clean [...] Dashboard: http://localhost:63387/_/dashboard ``` -- #### Step 3: Open another terminal window in the same directory: +- #### Step 2: Open another terminal window in the same directory: ```sh cd examples/rust/periodic_tasks ``` -- #### Step 4: Compile and deploy `heartbeat` and `timer` canisters, setting the interval for periodic tasks to 10s: +- #### Step 3: Compile and deploy the `heartbeat` and `timer` canisters, setting the interval for periodic tasks to 10s: ```sh dfx deploy heartbeat --argument 10 @@ -77,25 +73,25 @@ URLs: timer: http://127.0.0.1/... ``` -- #### Step 5: After 10s, observe similar non-zero counters in both canisters: +- #### Step 4: After 10s, observe similar non-zero counters in both canisters: ```sh dfx canister call heartbeat counter dfx canister call timer counter ``` -Note, as the canisters deployed one by one, there might be a minor discrepancy in the counters. +Note: As the canisters deployed one by one, there might be a minor discrepancy in the counters. Example output: ```sh -% dfx canister call heartbeat counter +% dfx canister call heartbeat counter (8 : nat32) -% dfx canister call timer counter +% dfx canister call timer counter (7 : nat32) ``` -- #### Step 6: Compare the amount of cycles used to schedule the periodic task with 10s interval: +- #### Step 5: Compare the amount of cycles used to schedule the periodic task with 10s interval: ```sh dfx canister call heartbeat cycles_used @@ -115,36 +111,40 @@ For periodic tasks with 10 sec intervals, the `heartbeat` canister uses *more* c Not only do timers use fewer cycles, but they are also more composable. As there is no global state or methods to export, different libraries with timers could be easily used in the same project. -Also, timers provide isolation between the scheduling logic and the periodic task. If the periodic task fails, all the changes made by this task will be reverted, but the timers library state will be updated, i.e. the failed task will be removed from the list of timers to execute. +Also, timers provide isolation between the scheduling logic and the periodic task. If the periodic task fails, all the changes made by this task will be reverted, but the timers library state will be updated, i.e., the failed task will be removed from the list of timers to execute. For such isolation of execution and scheduling contexts, the internal timers library uses self-canister calls: - ```rust - # This is a pseudo-code of a self call: - ic_cdk::call(ic_cdk::id(), "periodic_task", ()); - ``` +```rust +# This is a pseudo-code of a self call: +ic_cdk::call(ic_cdk::id(), "periodic_task", ()); +``` + +Despite the [costs](https://internetcomputer.org/docs/current/developer-docs/gas-cost) associated with such self-canister calls, the timers library still uses fewer cycles than the heartbeats. -Despite the [costs](https://internetcomputer.org/docs/current/developer-docs/production/computation-and-storage-costs) associated with such self-canister calls, the timers library still uses fewer cycles than the heartbeats. +## Example 2: Cycles usage for tasks with 1s interval -### Example 2: Cycles usage for tasks with 1s interval +- ### Step 1: Setup project environment -- #### Step 1: Open a new terminal window in the example root directory: +Navigate into the folder containing the project's files and start a local instance of the replica with the command: ```sh cd examples/rust/periodic_tasks +dfx start --clean ``` -- #### Step 2: Start a clean local Internet Computer replica and a web server: +This terminal will stay blocked, printing log messages, until the `Ctrl+C` is pressed or `dfx stop` command is run. + +Example output: ```sh -dfx stop dfx start --clean +[...] +Dashboard: http://localhost:63387/_/dashboard ``` -This terminal will stay blocked, printing log messages, until the `Ctrl+C` is pressed or `dfx stop` command is run. - -- #### Step 3: Open another terminal window in the same directory: +- #### Step 2: Open another terminal window in the same directory: ```sh cd examples/rust/periodic_tasks @@ -153,12 +153,12 @@ cd examples/rust/periodic_tasks Example output: ```sh -% dfx stop && dfx start --clean +dfx start --clean [...] Dashboard: http://localhost:63387/_/dashboard ``` -- #### Step 4:. Compile and deploy `heartbeat` and `timer` canisters, setting the interval for periodic tasks to 1s: +- #### Step 3:. Compile and deploy `heartbeat` and `timer` canisters, setting the interval for periodic tasks to 1s: ```sh dfx deploy --argument 1 heartbeat @@ -187,25 +187,25 @@ URLs: timer: http://127.0.0.1/... ``` -- #### Step 5: After a few seconds, observe similar non-zero counters in both canisters: +- #### Step 4: After a few seconds, observe similar non-zero counters in both canisters: ```sh dfx canister call heartbeat counter dfx canister call timer counter ``` -Note, as the canisters deployed one by one, there might be a minor discrepancy in the counters. +Note: As the canisters deployed one by one, there might be a minor discrepancy in the counters. Example output: ```sh -% dfx canister call heartbeat counter +% dfx canister call heartbeat counter (8 : nat32) -% dfx canister call timer counter +% dfx canister call timer counter (9 : nat32) ``` -- #### Step 6: Compare the number of cycles used to schedule the periodic task with 1s interval: +- #### Step 5: Compare the number of cycles used to schedule the periodic task with 1s interval: ```sh dfx canister call heartbeat cycles_used @@ -230,6 +230,7 @@ Also, there is no isolation between the scheduling logic and the periodic task. For such isolation of execution and scheduling contexts, the timers library uses internal self-canister calls as described in `Demo 1`. Due to the [costs](https://internetcomputer.org/docs/current/developer-docs/production/computation-and-storage-costs) associated with such self-canister calls, `timer` canister uses more cycles for very frequent periodic tasks. ## Further learning + 1. Have a look at the locally running dashboard. The URL is at the end of the `dfx start` command: `Dashboard: http://localhost/...` 2. Check out `heartbeat` and `timer` canisters Candid user interface. The URLs are at the end of the `dfx deploy` command: `heartbeat: http://127.0.0.1/...` 3. Find which interval makes even the costs of running periodic tasks in the `timer` and `heartbeat` canisters: `dfx deploy heartbeat --argument 5 && dfx deploy timer --argument 5` diff --git a/rust/pub-sub/README.md b/rust/pub-sub/README.md index df08528c3..fe483135f 100644 --- a/rust/pub-sub/README.md +++ b/rust/pub-sub/README.md @@ -1,12 +1,5 @@ ---- -keywords: [beginner, rust, pubsub, publisher, subscriber] ---- - # PubSub -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/pub-sub) - -## Overview This sample project demonstrates how functions may be passed as arguments of inter-canister calls to be used as callbacks. A common problem in both distributed and decentralized systems is keeping separate services (or canisters) synchronized with one another. While there are many potential solutions to this problem, a popular one is the Publisher/Subscriber pattern or "PubSub". PubSub is an especially valuable pattern on the Internet Computer as its primary drawback, message delivery failures, does not apply. @@ -14,43 +7,39 @@ A common problem in both distributed and decentralized systems is keeping separa ## Prerequisites This example requires an installation of: -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` Begin by opening a terminal window. -### Step 1: Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the command: +## Step 1: Setup project environment -```bash +Navigate into the folder containing the project's files and start a local instance of the replica with the command: + +```sh cd examples/rust/pub-sub dfx start --background ``` -### Step 2: Deploy the canister: - -```bash -dfx deploy -``` - -### Step 3: Get the publisher ID +## Step 2: Get the publisher ID ```bash dfx canister id publisher ``` -### Step 4: Subscribe to the "Apples" topic: +## Step 3: Subscribe to the "Apples" topic ```bash dfx canister call subscriber setup_subscribe '(principal "", "Apples")' ``` -### Step 5: Publish to the "Apples" topic: +## Step 4: Publish to the "Apples" topic ```bash dfx canister call publisher publish '(record { "topic" = "Apples"; "value" = 2 })' ``` -### Step 6: Receive your subscription: +## Step 5: Receive your subscription ```bash dfx canister call subscriber get_count diff --git a/rust/qrcode/README.md b/rust/qrcode/README.md index 6d1f453dd..2ab8afb6a 100644 --- a/rust/qrcode/README.md +++ b/rust/qrcode/README.md @@ -1,13 +1,5 @@ ---- -keywords: [intermediate, rust, qrcode] ---- - # QR code generator -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/qrcode) - -## Overview - This example shows that an Internet Computer dapp can perform a long-running computation, like image processing, in a single message execution. This is possible due to a unique feature called Deterministic Time Slicing (DTS), which automatically divides long computations into smaller slices executed across multiple blocks. Developers can write long-running code as usual and don't require anything special to take advantage of DTS, as demonstrated in this example. @@ -17,20 +9,19 @@ You try the live version of the dapp running on the mainnet here: [https://khpe2 ## Prerequisites This example requires an installation of: -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/). -- [x] Install `node.js` to build the web frontend. Make sure the version is at least `12.20`. -- [x] Make sure your rust version is up-to-date (e.g., run `rustup update`). +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). +- [x] Make sure your Rust version is up-to-date (e.g., run `rustup update`). - [x] Add the `wasm32` target to your rust installation (by running `rustup target add wasm32-unknown-unknown`). -- [x] Clone this project to a local directory. - [x] Install `node.js` dependencies by running `npm install`. - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` ## Running locally -Start a local replica of the Internet Computer by running: +Navigate into the folder containing the project's files and start a local instance of the replica with the command: -```bash -dfx start --background +```sh +cd examples/rust/qrcode +dfx start --clean --background ``` You can omit the `--background` argument if you want to see log messages of the dapp. diff --git a/rust/query_stats/README.md b/rust/query_stats/README.md index cdec34a6d..7e441ddfc 100644 --- a/rust/query_stats/README.md +++ b/rust/query_stats/README.md @@ -1,13 +1,5 @@ ---- -keywords: [beginner, rust, query statistics] ---- - # Query statistics -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/query_stats) - -## Overview - This example shows to work with the query stats feature. ## Architecture @@ -27,37 +19,41 @@ The `load` function just returns a timestamp. It just exists such that there is a query endpoint to call. The `get_query_stats` is the function that queries the status endpoint and returns the collected query statistics. -### Prerequisites +## Prerequisites + This example requires an installation of: -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). -- [x] Install `node.js` (to build the web frontend). +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` - ### Step 1: Start a local canister execution environment: +## Step 1: Setup project environment -``` -dfx start --background +Navigate into the folder containing the project's files and start a local instance of the replica with the command: + +```sh +cd examples/rust/query_stats +dfx start --clean ``` - ### Step 2: Register, build, and deploy the project with the command: +## Step 2: Compile and deploy `query_stats` canister -``` +```sh dfx deploy ``` - ### Step 3: Call the canisters load function a few times to generate query traffic: +## Step 3: Call the canister's load function a few times to generate query traffic ``` dfx canister call query_stats load ``` - ### Step 4: Observe the following result: +## Step 4: Observe the following result ``` dfx canister call query_stats get_query_stats ``` - ### Step 5: After a while, the values should become populated +## Step 5: After a while, the values should become populated ``` "Number of calls: 19 - Number of instructions 414_083 - Request payload bytes: 114 - Response payload bytes: 270" @@ -79,7 +75,8 @@ Their raw values are not that useful, you may want to implement some sort of met One way to go from here is to get the query stats in a regular interval using a timer and compare to the last values, calculating rates. -### Resources +## Resources + - [ic-cdk](https://docs.rs/ic-cdk/latest/ic_cdk/). ## Security considerations and security best practices diff --git a/rust/send_http_get/README.md b/rust/send_http_get/README.md index a5cf2731c..b5bbf59c0 100644 --- a/rust/send_http_get/README.md +++ b/rust/send_http_get/README.md @@ -1,11 +1,5 @@ ---- -keywords: [intermediate, rust, http, get, http get] ---- - # HTTP: GET -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/send_http_get) - The purpose of this dapp is to give developers a minimal dapp that uses the IC's HTTPS outcalls feature to make a `GET` request. This demo goes in hand with the [developer documentation on HTTPS outcalls](https://internetcomputer.org/docs/current/developer-docs/integrations/https-outcalls/https-outcalls-get). @@ -13,18 +7,8 @@ This demo goes in hand with the [developer documentation on HTTPS outcalls](http If you want to start working on your project right away, you might want to try the following commands: ```bash +git clone https://github.com/dfinity/examples cd examples/rust/send_http_get -dfx help -dfx canister --help -``` - -## Running the project locally -If you want to test your project locally, you can use the following commands: - -```bash -# Starts the replica, running in the background dfx start --background - -# Deploys your canisters to the replica and generates your candid interface dfx deploy ``` diff --git a/rust/send_http_post/README.md b/rust/send_http_post/README.md index af6df1f8f..b9ef3e131 100644 --- a/rust/send_http_post/README.md +++ b/rust/send_http_post/README.md @@ -1,11 +1,5 @@ ---- -keywords: [intermediate, rust, http, post, http post] ---- - # HTTP: POST -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/send_http_post) - The purpose of this dapp is to give developers a minimal dapp that uses the IC's HTTPS outcalls feature to make a `POST` request. This demo goes in hand with the [developer documentation on HTTPS outcalls](https://internetcomputer.org/docs/current/developer-docs/integrations/https-outcalls/https-outcalls-post). @@ -13,20 +7,8 @@ This demo goes in hand with the [developer documentation on HTTPS outcalls](http If you want to start working on your project right away, you might want to try the following commands: ```bash +git clone https://github.com/dfinity/examples cd examples/rust/send_http_post -dfx help -dfx canister --help -``` - -## Running the project locally - -If you want to test your project locally, you can use the following commands: - -```bash -# Starts the replica, running in the background dfx start --background - -# Deploys your canisters to the replica and generates your candid interface dfx deploy -``` - +``` \ No newline at end of file diff --git a/rust/simd/README.md b/rust/simd/README.md index 59b13a020..0bc57b5f8 100644 --- a/rust/simd/README.md +++ b/rust/simd/README.md @@ -1,13 +1,5 @@ ---- -keywords: [advanced, rust, simd, ai] ---- - # WebAssembly SIMD Example -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/simd) - -## Overview - Unlike other blockchains, the Internet Computer supports WebAssembly SIMD ([Single Instruction, Multiple Data](https://en.wikipedia.org/wiki/Single_instruction,_multiple_data)) instructions. This, combined with state-of-the-art Rust compiler support, @@ -21,42 +13,34 @@ The example consists of a canister named `mat_mat_mul` (matrix-matrix multiplica This example requires an installation of: -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). Note: the WebAssembly SIMD support requires `dfx` version `0.20.2-beta.0` or later. +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). Note: the WebAssembly SIMD support requires `dfx` version `0.20.2-beta.0` or later. - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` ### Example 1: Floating point matrices multiplications -- #### Step 1.1: Begin by opening a terminal window and navigating into the project's directory +- #### Step 1: Setup project environment -```sh -cd examples/rust/simd -``` - -- #### Step 1.2: Start a clean local Internet Computer replica and a web server +Navigate into the folder containing the project's files and start a local instance of the replica with the command: ```sh -dfx stop +cd examples/rust/simd dfx start --clean ``` -This terminal will stay blocked, printing log messages, until the `Ctrl+C` is pressed or `dfx stop` command is run. - -Example output: - ```sh -% dfx stop && dfx start --clean +dfx start --clean Running dfx start for version 0.20.2-beta.0 [...] Dashboard: http://localhost:63387/_/dashboard ``` -- #### Step 1.3: Open another terminal window in the same directory +- #### Step 2: Open another terminal window in the same directory ```sh cd examples/rust/simd ``` -- #### Step 1.4: Compile and deploy `mat_mat_mul` canister +- #### Step 3: Compile and deploy `mat_mat_mul` canister ```sh dfx deploy @@ -73,7 +57,7 @@ URLs: mat_mat_mul: http://127.0.0.1/?canisterId=... ``` -- #### Step 1.5: Compare the amount of instructions used for different matrix multiplication implementations +- #### Step 4: Compare the amount of instructions used for different matrix multiplication implementations Call a loop performing 1K element-wise multiplications of `K x 4` packed slices from matrices `A` and `B` using optimized algorithm, the same algorithm with @@ -100,44 +84,31 @@ In this example, Rust's auto-vectorization shines in optimizing matrix multiplic The auto-vectorized code achieves over 10x speedup compared to the optimized version! Also, it's on par with the hand-crafted WebAssembly SIMD multiplication. -It's important to note that the optimized code's performance is currently limited -due to a known issue with NaN canonicalization in `wasmtime`. -This issue [has been fixed](https://github.com/bytecodealliance/wasmtime/commit/72a3b8b99d7c0343bacb7cd2cff3151b0144179d) -by DFINITY, but not yet released at the time of writing. - ### Example 2: Integer matrices multiplications -- #### Step 2.1: Begin by opening a terminal window and navigating into the project's directory - -```sh -cd examples/rust/simd -``` +- #### Step 1: Setup project environment -- #### Step 2.2: Start a clean local Internet Computer replica and a web server +Navigate into the folder containing the project's files and start a local instance of the replica with the command: ```sh -dfx stop +cd examples/rust/simd dfx start --clean ``` -This terminal will stay blocked, printing log messages, until the `Ctrl+C` is pressed or `dfx stop` command is run. - -Example output: - ```sh -% dfx stop && dfx start --clean +dfx start --clean Running dfx start for version 0.20.2-beta.0 [...] Dashboard: http://localhost:63387/_/dashboard ``` -- #### Step 2.3: Open another terminal window in the same directory +- #### Step 2: Open another terminal window in the same directory ```sh cd examples/rust/simd ``` -- #### Step 2.4: Compile and deploy `mat_mat_mul` canister +- #### Step 3: Compile and deploy `mat_mat_mul` canister ```sh dfx deploy @@ -154,7 +125,7 @@ URLs: mat_mat_mul: http://127.0.0.1/?canisterId=... ``` -- #### Step 2.5: Compare the amount of instructions used for different matrix multiplication implementations +- #### Step 4: Compare the amount of instructions used for different matrix multiplication implementations Call a loop performing 1K element-wise multiplications of `K x 4` packed slices from matrices `A` and `B` using optimized algorithm and the same algorithm diff --git a/rust/threshold-ecdsa/README.md b/rust/threshold-ecdsa/README.md index 9b699c21d..031be0e66 100644 --- a/rust/threshold-ecdsa/README.md +++ b/rust/threshold-ecdsa/README.md @@ -1,50 +1,42 @@ ---- -keywords: [advanced, rust, threshold ecdsa, ecdsa, signature] ---- +# Threshold ECDSA sample -# Threshold ECDSA +We present a minimal example canister smart contract for showcasing the [threshold ECDSA](https://internetcomputer.org/docs/current/developer-docs/integrations/t-ecdsa) API. -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/threshold-ecdsa) - -## Overview - -We present a minimal example canister smart contract for showcasing the [threshold ECDSA](https://internetcomputer.org/docs/current/developer-docs/integrations/t-ecdsa) API. - -The example canister is a signing oracle that creates ECDSA signatures with keys derived from an input string. +The example canister is a signing oracle that creates ECDSA signatures with keys derived from an input string. More specifically: - The sample canister receives a request that provides a message. -- The sample canister hashes the message and uses the key derivation string for the derivation path. +- The sample canister hashes the message and uses the key derivation string for the derivation path. - The sample canister uses the above to request a signature from the threshold ECDSA [subnet](https://wiki.internetcomputer.org/wiki/Subnet_blockchain) (the threshold ECDSA is a subnet specializing in generating threshold ECDSA signatures). -This tutorial gives a complete overview of the development, starting with downloading [`dfx`](https://internetcomputer.org/docs/current/developer-docs/setup/index.md), up to the deployment and trying out the code on the mainnet. - -This walkthrough focuses on the version of the sample canister code written in [Motoko](https://internetcomputer.org/docs/current/developer-docs/backend/motoko/index.md) programming language, but no specific knowledge of Motoko is needed to follow along. There is also a [Rust](https://github.com/dfinity/examples/tree/master/rust/threshold-ecdsa) version available in the same repo and follows the same commands for deploying. +This tutorial gives a complete overview of the development, starting with downloading the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/index.md), up to the deployment and trying out the code on the IC mainnet. +> [!TIP] +> This walkthrough focuses on the version of the sample canister code written in the Rust programming language. There is also a [Motoko](https://internetcomputer.org/docs/current/developer-docs/backend/motoko/index.md) version available in the same repo and follows the same commands for deploying. ## Prerequisites -- [x] Download and [install the IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/index.md) if you do not already have it. -- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` +This example requires an installation of: -## Getting started +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install) v0.11.0 or newer. +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -Sample code for `threshold-ecdsa` is provided in the [examples repository](https://github.com/dfinity/examples), under either [`/motoko`](https://github.com/dfinity/examples/tree/master/motoko/threshold-ecdsa) or [`/rust`](https://github.com/dfinity/examples/tree/master/rust/threshold-ecdsa) sub-directories. It requires at least [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/index.md) version 0.11.0 for local development. +Begin by opening a terminal window. -### Deploy and test the canister locally +## Step 1: Setup the project environment -This tutorial will use the Rust version of the canister: +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: ```bash cd examples/rust/threshold-ecdsa dfx start --background -npm install -dfx deploy ``` -#### What this does -- `dfx start --background` starts a local instance of the IC via the IC SDK -- `dfx deploy` deploys the code in the user's directory as a canister on the local version of the IC +## Step 2: Deploy the canisters + +```bash +dfx deploy +``` If successful, you should see something like this: @@ -52,25 +44,25 @@ If successful, you should see something like this: Deployed canisters. URLs: Backend canister via Candid interface: - ecdsa_example_motoko: http://127.0.0.1:4943/?canisterId=t6rzw-2iaaa-aaaaa-aaama-cai&id=st75y-vaaaa-aaaaa-aaalq-cai + ecdsa_example_rust: http://127.0.0.1:4943/?canisterId=t6rzw-2iaaa-aaaaa-aaama-cai&id=st75y-vaaaa-aaaaa-aaalq-cai ``` If you open the URL in a web browser, you will see a web UI that shows the public methods the canister exposes. Since the canister exposes `public_key` and `sign` methods, those are rendered in the web UI. -### Deploying the canister on the mainnet +## Deploying the canister on the mainnet -To deploy this canister the mainnet, one needs to do two things: +To deploy this canister to the mainnet, one needs to do two things: -- Acquire cycles (equivalent of "gas" in other blockchains). This is necessary for all canisters. +- Acquire cycles (the equivalent of "gas" on other blockchains). This is necessary for all canisters. - Update the sample source code to have the right key ID. This is unique to this canister. -#### Acquire cycles to deploy +### Acquire cycles to deploy Deploying to the Internet Computer requires [cycles](https://internetcomputer.org/docs/current/developer-docs/getting-started/tokens-and-cycles) (the equivalent of "gas" on other blockchains). -#### Update source code with the right key ID +### Update source code with the right key ID -To deploy the sample code, the canister needs the right key ID for the right environment. Specifically, one needs to replace the value of the `key_id` in the `src/ecdsa_example_rust/main.mo` file of the sample code. Before deploying to mainnet, one should modify the code to use the right name of the `key_id`. +To deploy the sample code, the canister needs the right key ID for the right environment. Specifically, one needs to replace the value of the `key_id` in the `src/ecdsa_example_rust/main.mo` file of the sample code. Before deploying to the mainnet, one should modify the code to use the right name of the `key_id`. There are three options: @@ -78,35 +70,12 @@ There are three options: * `test_key_1`: a master **test** key ID that is used in mainnet. * `key_1`: a master **production** key ID that is used in mainnet. -For example, the default code in `src/ecdsa_example_motoko/main.mo` includes the following lines and can be deployed locally: +> [!WARNING] +> To deploy to IC mainnet, one needs to replace the value in `key_id` fields with the values `"dfx_test_key"` to instead have either `"test_key_1"` or `"key_1"` depending on the desired intent. -:::caution -The following example is two **code snippets** that are part of a larger code file. These snippets may return an error if run on their own. -::: +### Deploying -```motoko -let { public_key } = await ic.ecdsa_public_key({ - canister_id = null; - derivation_path = [ caller ]; - key_id = { curve = #secp256k1; name = "dfx_test_key" }; -}); -``` - -```motoko -let { signature } = await ic.sign_with_ecdsa({ - message_hash; - derivation_path = [ caller ]; - key_id = { curve = #secp256k1; name = "dfx_test_key" }; -}); -``` - -:::caution -To deploy to IC mainnet, one needs to replace the value in `key_id` fields with the values `"dfx_test_key"` to instead have either `"test_key_1"` or `"key_1"` depending on the desired intent. -::: - -#### Deploy to the mainnet via IC SDK - -To [deploy via the mainnet](https://internetcomputer.org/docs/current/developer-docs/setup/deploy-mainnet.md), run the following commands: +To [deploy via mainnet](https://internetcomputer.org/docs/current/developer-docs/setup/deploy-mainnet.md), run the following commands: ```bash npm install @@ -118,14 +87,14 @@ If successful, you should see something like this: Deployed canisters. URLs: Backend canister via Candid interface: - ecdsa_example_motoko: https://a3gq9-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=736w4-cyaaa-aaaal-qb3wq-cai + ecdsa_example_rust: https://a3gq9-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=736w4-cyaaa-aaaal-qb3wq-cai ``` -In the example above, `ecdsa_example_motoko` has the URL https://a3gq9-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=736w4-cyaaa-aaaal-qb3wq-cai and serves up the Candid web UI for this particular canister deployed on mainnet. +In the example above, `ecdsa_example_rust` has the URL https://a3gq9-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=736w4-cyaaa-aaaal-qb3wq-cai and serves up the Candid web UI for this particular canister deployed on mainnet. ## Obtaining public keys -### Using the Candid Web UI +### Using the Candid UI If you deployed your canister locally or to the mainnet, you should have a URL to the Candid web UI where you can access the public methods. We can call the `public-key` method. @@ -136,49 +105,10 @@ In the example below, the method returns `03c22bef676644dba524d4a24132ea8463221a "Ok": { "public_key_hex": "03c22bef676644dba524d4a24132ea8463221a55540a27fc86d690fda8e688e31a" - } + } } ``` - -### Code walkthrough -Open the file `main.mo`, which will show the following Motoko code that demonstrates how to obtain an ECDSA public key. - -```motoko - //declare "ic" to be the management canister, which is evoked by `actor("aaaaa-aa")`. This is how we will obtain an ECDSA public key - let ic : IC = actor("aaaaa-aa"); - - public shared (msg) func public_key() : async { #Ok : { public_key: Blob }; #Err : Text } { - let caller = Principal.toBlob(msg.caller); - - try { - - //request the management canister to compute an ECDSA public key - let { public_key } = await ic.ecdsa_public_key({ - - //When `null`, it defaults to getting the public key of the canister that makes this call - canister_id = null; - derivation_path = [ caller ]; - //this code uses the mainnet test key - key_id = { curve = #secp256k1; name = "test_key_1" }; - }); - - #Ok({ public_key }) - - } catch (err) { - - #Err(Error.message(err)) - - } - - }; -``` - -In the code above, the canister calls the `ecdsa_public_key` method of the [IC management canister](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-management-canister) (`aaaaa-aa`). - - -**The [IC management canister](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-management-canister) is just a facade; it does not exist as a canister (with isolated state, Wasm code, etc.). It is an ergonomic way for canisters to call the system API of the IC (as if it were a single canister). In the code below, we use the management canister to create an ECDSA public key. `let ic : IC = actor("aaaaa-aa")` declares the IC management canister in the code above.** - ### Canister root public key For obtaining the canister's root public key, the derivation path in the API can be simply left empty. @@ -190,25 +120,7 @@ For obtaining the canister's root public key, the derivation path in the API can ## Signing -Computing threshold ECDSA signatures is the core functionality of this feature. **Canisters do not hold ECDSA keys themselves**, but keys are derived from a master key held by dedicated subnets. A canister can request the computation of a signature through the management canister API. The request is then routed to a subnet holding the specified key and the subnet computes the requested signature using threshold cryptography. Thereby, it derives the canister root key or a key obtained through further derivation, as part of the signature protocol, from a shared secret and the requesting canister's principal identifier. Thus, a canister can only request signatures to be created for its canister root key or a key derived from it. This means, that canisters "control" their private ECDSA keys in that they decide when signatures are to be created with them, but don't hold a private key themselves. - -```motoko - public shared (msg) func sign(message_hash: Blob) : async { #Ok : { signature: Blob }; #Err : Text } { - assert(message_hash.size() == 32); - let caller = Principal.toBlob(msg.caller); - try { - Cycles.add(10_000_000_000); - let { signature } = await ic.sign_with_ecdsa({ - message_hash; - derivation_path = [ caller ]; - key_id = { curve = #secp256k1; name = "dfx_test_key" }; - }); - #Ok({ signature }) - } catch (err) { - #Err(Error.message(err)) - } - }; -``` +Computing threshold ECDSA signatures is the core functionality of this feature. **Canisters do not hold ECDSA keys themselves**, but keys are derived from a master key held by dedicated subnets. A canister can request the computation of a signature through the management canister API. The request is then routed to a subnet holding the specified key and the subnet computes the requested signature using threshold cryptography. Thereby, it derives the canister root key or a key obtained through further derivation, as part of the signature protocol, from a shared secret and the requesting canister's principal identifier. Thus, a canister can only request signatures to be created for its canister root key or a key derived from it. This means that canisters "control" their private ECDSA keys in that they decide when signatures are to be created with them, but don't hold a private key themselves. ## Signature verification @@ -236,4 +148,4 @@ In this walkthrough, we deployed a sample smart contract that: * Signed with private ECDSA keys even though **canisters do not hold ECDSA keys themselves**. * Requested a public key. -* Performed signature verification. +* Performed signature verification. \ No newline at end of file diff --git a/rust/threshold-schnorr/README.md b/rust/threshold-schnorr/README.md index 11ef6b1ca..45ed865d6 100644 --- a/rust/threshold-schnorr/README.md +++ b/rust/threshold-schnorr/README.md @@ -1,17 +1,6 @@ ---- -keywords: [advanced, rust, threshold schnorr, schnorr, signature] ---- - # Threshold Schnorr -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/threshold-schnorr) - -## Overview - -We present a minimal example canister smart contract for showcasing the -[threshold -Schnorr](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-sign_with_schnorr) -API. +We present a minimal example canister smart contract for showcasing the [threshold Schnorr](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-sign_with_schnorr) API. The example canister is a signing oracle that creates Schnorr signatures with keys derived based on the canister ID and the chosen algorithm, either BIP340 or @@ -26,40 +15,48 @@ More specifically: (the threshold Schnorr subnet is a subnet generating threshold Schnorr signatures). -This tutorial gives a complete overview of the development, starting with downloading [`dfx`](https://internetcomputer.org/docs/current/developer-docs/setup/index.md), up to the deployment and trying out the code on the mainnet. - This walkthrough focuses on the version of the sample canister code written in -Rust programming language.. There is also a -[Motoko](https://github.com/dfinity/examples/tree/master/motoko/threshold-schnorr) -version available in the same repo and follows the same commands for deploying. - +[Rust](https://github.com/dfinity/examples/tree/master/rust/threshold-schnorr). +There is also a Motoko version available in the same repo and follows the same commands for deploying. ## Prerequisites -- [x] Download and [install the IC - SDK](https://internetcomputer.org/docs/current/developer-docs/setup/index.md) - if you do not already have it. For local testing, `dfx >= 0.22.0-beta.0` is - required. -- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` +This example requires an installation of: -## Getting started +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -Sample code for `threshold-schnorr-example` is provided in the [examples repository](https://github.com/dfinity/examples), under either [`/motoko`](https://github.com/dfinity/examples/tree/master/motoko/threshold-schnorr) or [`/rust`](https://github.com/dfinity/examples/tree/master/rust/threshold-schnorr) sub-directories. +Begin by opening a terminal window. -### Deploy the canister locally +## Step 1: Setup the project environment -This tutorial will use the Rust version of the canister: +Navigate into the folder containing the project's files, start a local instance of the Internet Computer and with the commands: ```bash cd examples/rust/threshold-schnorr dfx start --background -make deploy ``` #### What this does - `dfx start --background` starts a local instance of the IC via the IC SDK + +## Step 2: Deploy the canisters + +```bash +make deploy +``` + +To test (includes deploying): +```bash +npm install @noble/curves +make test +``` + +#### What this does - `make deploy` deploys the canister code on the local version of the IC +- `npm install @noble/curves` installs a test javascript dependency +- `make test` deploys and tests the canister code on the local version of the IC -If successful, you should see something like this: +If deployment was successful, you should see something like this: ```bash Deployed canisters. @@ -69,21 +66,21 @@ URLs: ``` If you open the URL in a web browser, you will see a web UI that shows the -public methods the canister exposes. Since the canister exposes `public_key`, -`sign`, and `verify` methods, those are rendered in the web UI. +public methods the canister exposes. Since the canister exposes `public_key` and +`sign`, those are rendered in the web UI. -### Deploying the canister on the mainnet +## Deploying the canister on the mainnet To deploy this canister the mainnet, one needs to do two things: - Acquire cycles (equivalent of "gas" in other blockchains). This is necessary for all canisters. - Update the sample source code to have the right key ID. This is unique to this canister. -#### Acquire cycles to deploy +### Acquire cycles to deploy Deploying to the Internet Computer requires [cycles](https://internetcomputer.org/docs/current/developer-docs/getting-started/tokens-and-cycles) (the equivalent of "gas" on other blockchains). -#### Update source code with the right key ID +### Update source code with the right key ID To deploy the sample code, the canister needs the right key ID for the right environment. Specifically, one needs to replace the value of the `key_id` in the `src/schnorr_example_rust/src/lib.rs` file of the sample code. Before deploying to mainnet, one should modify the code to use the right name of the `key_id`. @@ -93,19 +90,12 @@ There are three options that are planed to be supported: * `test_key_1`: a master **test** key ID that is used in mainnet. * `key_1`: a master **production** key ID that is used in mainnet. -For example, the default code in `src/schnorr_example_rust/src/lib.rs` derives -the key ID as follows and can be deployed locally: -```rust -SchnorrKeyIds::TestKeyLocalDevelopment.to_key_id(algorithm) -``` +IMPORTANT: To deploy to IC mainnet, one needs to replace `"dfx_test_key"` with +either "test_key_1"` or `"key_1"` depending on the desired intent. Both uses of +key ID in `src/schnorr_example_rust/src/main.mo` must be consistent. -IMPORTANT: To deploy to IC mainnet, one needs to replace -`SchnorrKeyIds::TestKeyLocalDevelopment` (which maps to the `"dfx_test_key"` key -id) with either `SchnorrKeyIds::TestKey1` (`"test_key_1"`) or -`SchnorrKeyIds::ProductionKey1` (`"key_1"`) depending on the desired intent. -Both uses of key ID in `src/schnorr_example_rust/src/lib.rs` must be consistent. -#### Deploy to the mainnet via IC SDK +### Deploying To [deploy via the mainnet](https://internetcomputer.org/docs/current/developer-docs/setup/deploy-mainnet.md), run the following commands: @@ -121,11 +111,15 @@ URLs: schnorr_example_rust: https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=enb64-iaaaa-aaaap-ahnkq-cai ``` -In the example above, `schnorr_example_rust` has the URL https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=enb64-iaaaa-aaaap-ahnkq-cai and serves up the Candid web UI for this particular canister deployed on mainnet. +The implementation of this canister in Rust is (`schnorr_example_rust`) is +deployed on mainnet. It has the URL +https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=enb64-iaaaa-aaaap-ahnkq-cai +and serves up the Candid web UI for this particular canister deployed on +mainnet. ## Obtaining public keys -### Using the Candid Web UI +### Using the Candid UI If you deployed your canister locally or to the mainnet, you should have a URL to the Candid web UI where you can access the public methods. We can call the `public-key` method. @@ -142,42 +136,6 @@ Ed25519 public key. } ``` - -### Code walkthrough -Open the file `lib.rs`, which will show the following Rust code that -demonstrates how to obtain a Schnorr public key. - -```rust -#[update] -async fn public_key(algorithm: SchnorrAlgorithm) -> Result { - let request = ManagementCanisterSchnorrPublicKeyRequest { - canister_id: None, - derivation_path: vec![ic_cdk::api::caller().as_slice().to_vec()], - key_id: SchnorrKeyIds::TestKeyLocalDevelopment.to_key_id(algorithm), - }; - - let (res,): (ManagementCanisterSchnorrPublicKeyReply,) = - ic_cdk::call(Principal::management_canister(), "schnorr_public_key", (request,)) - .await - .map_err(|e| format!("schnorr_public_key failed {}", e.1))?; - - Ok(PublicKeyReply { - public_key_hex: hex::encode(&res.public_key), - }) -} -``` - -In the code above, the canister calls the `schnorr_public_key` method of the [IC management canister](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-management-canister) (`aaaaa-aa`). - - -**The [IC management -canister](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-management-canister) -is just a facade; it does not exist as a canister (with isolated state, Wasm -code, etc.). It is an ergonomic way for canisters to call the system API of the -IC (as if it were a single canister). In the code below, we use the management -canister to create a Schnorr public key. Canister ID `"aaaaa-aa"` -declares the IC management canister in the canister code.** - ### Canister root public key For obtaining the canister's root public key, the derivation path in the API can be simply left empty. @@ -185,105 +143,51 @@ For obtaining the canister's root public key, the derivation path in the API can ### Key derivation - For obtaining a canister's public key below its root key in the BIP-32 key derivation hierarchy, a derivation path needs to be specified. As explained in the general documentation, each element in the array of the derivation path is either a 32-bit integer encoded as 4 bytes in big endian or a byte array of arbitrary length. The element is used to derive the key in the corresponding level at the derivation hierarchy. -- In the example code above, we use the bytes extracted from the msg.caller principal in the `derivation_path`, so that different callers of `public_key()` method of our canister will be able to get their own public keys. +- In the example code above, we use the bytes extracted from the `msg.caller` principal in the `derivation_path`, so that different callers of `public_key()` method of our canister will be able to get their own public keys. ## Signing Computing threshold Schnorr signatures is the core functionality of this feature. **Canisters do not hold Schnorr keys themselves**, but keys are derived from a master key held by dedicated subnets. A canister can request the computation of a signature through the management canister API. The request is then routed to a subnet holding the specified key and the subnet computes the requested signature using threshold cryptography. Thereby, it derives the canister root key or a key obtained through further derivation, as part of the signature protocol, from a shared secret and the requesting canister's principal identifier. Thus, a canister can only request signatures to be created for its canister root key or a key derived from it. This means, that canisters "control" their private Schnorr keys in that they decide when signatures are to be created with them, but don't hold a private key themselves. -```rust -#[update] -async fn sign(message: String, algorithm: SchnorrAlgorithm) -> Result { - let internal_request = ManagementCanisterSignatureRequest { - message: message.as_bytes().to_vec(), - derivation_path: vec![ic_cdk::api::caller().as_slice().to_vec()], - key_id: SchnorrKeyIds::TestKeyLocalDevelopment.to_key_id(algorithm), - }; - - let (internal_reply,): (ManagementCanisterSignatureReply,) = - ic_cdk::api::call::call_with_payment( - Principal::management_canister(), - "sign_with_schnorr", - (internal_request,), - 25_000_000_000, - ) - .await - .map_err(|e| format!("sign_with_schnorr failed {e:?}"))?; - - Ok(SignatureReply { - signature_hex: hex::encode(&internal_reply.signature), - }) -} -``` - ## Signature verification For completeness of the example, we show that the created signatures can be verified with the public key corresponding to the same canister and derivation -path. Note that the first byte of the BIP340 public key needs to be removed for -verification, which is done by the verification function below internally. - -```rust -#[query] -async fn verify( - signature_hex: String, - message: String, - public_key_hex: String, - algorithm: SchnorrAlgorithm, -) -> Result { - let sig_bytes = hex::decode(&signature_hex).expect("failed to hex-decode signature"); - let msg_bytes = message.as_bytes(); - let pk_bytes = hex::decode(&public_key_hex).expect("failed to hex-decode public key"); - - match algorithm { - SchnorrAlgorithm::Bip340Secp256k1 => { - verify_bip340_secp256k1(&sig_bytes, msg_bytes, &pk_bytes) - } - SchnorrAlgorithm::Ed25519 => verify_ed25519(&sig_bytes, &msg_bytes, &pk_bytes), - } -} - -fn verify_bip340_secp256k1( - sig_bytes: &[u8], - msg_bytes: &[u8], - secp1_pk_bytes: &[u8], -) -> Result { - assert_eq!(secp1_pk_bytes.len(), 33); - assert_eq!(sig_bytes.len(), 64); +path in javascript. Note that in contrast to the Rust implementation of this +example, the signature verification is not part of the canister API and happens +externally. - let sig = - k256::schnorr::Signature::try_from(sig_bytes).expect("failed to deserialize signature"); +Ed25519 can be verified as follows: +```javascript +import('@noble/curves/ed25519').then((ed25519) => { verify(ed25519.ed25519); }) + .catch((err) => { console.log(err) }); - let vk = k256::schnorr::VerifyingKey::from_bytes(&secp1_pk_bytes[1..]) - .expect("failed to deserialize BIP340 encoding into public key"); +function verify(ed25519) { + const test_sig = '1efa03b7b7f9077449a0f4b3114513f9c90ccf214166a8907c23d9c2bbbd0e0e6e630f67a93c1bd525b626120e86846909aedf4c58763ae8794bcef57401a301' + const test_pubkey = '566d53caf990f5f096d151df70b2a75107fac6724cb61a9d6d2aa63e1496b003' + const test_msg = Uint8Array.from(Buffer.from("hello", 'utf8')); - let is_signature_valid = vk.verify_raw(&msg_bytes, &sig).is_ok(); - - Ok(SignatureVerificationReply { is_signature_valid }) -} - -fn verify_ed25519( - sig_bytes: &[u8], - msg_bytes: &[u8], - pk_bytes: &[u8], -) -> Result { - use ed25519_dalek::{Signature, Verifier, VerifyingKey}; - - let pk: [u8; 32] = pk_bytes - .try_into() - .expect("ed25519 public key incorrect length"); - let vk = VerifyingKey::from_bytes(&pk).unwrap(); + console.log(ed25519.verify(test_sig, test_msg, test_pubkey)); + } +``` - let signature = Signature::from_slice(sig_bytes).expect("ed25519 signature incorrect length"); +BIP340 can be verified as follows: +```javascript +import('@noble/curves/secp256k1').then((bip340) => { verify(bip340.schnorr); }) + .catch((err) => { console.log(err) }); - let is_signature_valid = vk.verify(msg_bytes, &signature).is_ok(); +function verify(bip340) { + const test_sig = '1b64ca7a7f02c76633954f320675267685b3b80560eb6a35cda20291ddefc709364e59585771c284e46264bfbb0620e23eb8fb274994f7a6f2fcbc8a9430e5d7'; + // the first byte of the BIP340 public key is truncated + const pubkey = '0341d7cf39688e10b5f11f168ad0a9e790bcb429d7d486eab07d2c824b85821470'.substring(2) + const test_msg = Uint8Array.from(Buffer.from("hello", 'utf8')); - Ok(SignatureVerificationReply { is_signature_valid }) + console.log(bip340.verify(test_sig, test_msg, test_pubkey)); } ``` The call to `verify` function should always return `true` for correct parameters -and `false` or trap on errors otherwise. +and `false` or error otherwise. Similar verifications can be done in many other languages with the help of cryptographic libraries that support the `bip340secp256k1` signing *with diff --git a/rust/token_transfer/README.md b/rust/token_transfer/README.md index 47a94e465..2bbcf18f1 100644 --- a/rust/token_transfer/README.md +++ b/rust/token_transfer/README.md @@ -1,8 +1,5 @@ # Token transfer -[View this samples code on GitHub](https://github.com/dfinity/examples/tree/master/rust/token_transfer). - -## Overview Token transfer is a canister that can transfer ICRC-1 tokens from its account to other accounts. It is an example of a canister that uses an ICRC-1 ledger canister. Sample code is available in [Motoko](https://github.com/dfinity/examples/tree/master/motoko/token_transfer) and [Rust](https://github.com/dfinity/examples/tree/master/rust/token_transfer). @@ -16,27 +13,17 @@ This sample will use the Rust variant. This example requires an installation of: -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). -- [x] Download and install [git.](https://git-scm.com/downloads) - -## How to get there - -The following steps will guide you through the process of setting up the token transfer canister for your own project. - -:::info - -If you just want to interact with this example, follow steps 4-8 and 10-12 below. - -::: +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -### Step 1: Create a new `dfx` project and navigate into the project's directory. +## Step 1: Create a new `dfx` project and navigate into the project's directory ```bash dfx new --type=rust token_transfer --no-frontend cd token_transfer ``` -### Step 2: Determine ICRC-1 ledger file locations +## Step 2: Determine ICRC-1 ledger file locations :::info @@ -44,22 +31,22 @@ You can read more about how to [setup the ICRC-1 ledger locally](https://interne ::: -Go to the [releases overview](https://dashboard.internetcomputer.org/releases) and copy the latest replica binary revision. At the time of writing, this is `d87954601e4b22972899e9957e800406a0a6b929`. +Go to the [releases overview](https://dashboard.internetcomputer.org/releases) and copy the latest replica binary revision. -The URL for the ledger Wasm module is `https://download.dfinity.systems/ic//canisters/ic-icrc1-ledger.wasm.gz`, so with the above revision it would be `https://download.dfinity.systems/ic/d87954601e4b22972899e9957e800406a0a6b929/canisters/ic-icrc1-ledger.wasm.gz`. +The URL for the ledger Wasm module is `https://download.dfinity.systems/ic//canisters/ic-icrc1-ledger.wasm.gz`. -The URL for the ledger .did file is `https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icrc1/ledger/ledger.did`, so with the above revision it would be `https://raw.githubusercontent.com/dfinity/ic/d87954601e4b22972899e9957e800406a0a6b929/rs/rosetta-api/icrc1/ledger/ledger.did`. +The URL for the ledger .did file is `https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icrc1/ledger/ledger.did`. **OPTIONAL:** If you want to make sure, you have the latest ICRC-1 ledger files you can run the following script. ```sh -curl -o download_latest_icrc1_ledger.sh "https://raw.githubusercontent.com/dfinity/ic/326df23607fc8280a047daba2d8462f1dfc57466/rs/rosetta-api/scripts/download_latest_icrc1_ledger.sh" +curl -o download_latest_icrc1_ledger.sh "https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/scripts/download_latest_icrc1_ledger.sh" chmod +x download_latest_icrc1_ledger.sh ./download_latest_icrc1_ledger.sh ``` -### Step 3: Configure the `dfx.json` file to use the ledger : +## Step 3: Configure the `dfx.json` file to use the ledger Replace its contents with this but adapt the URLs to be the ones you determined in step 2. Note that we are deploying the ICRC-1 ledger to the same canister id the ckBTC ledger uses on mainnet. This will make it easier to interact with it later. @@ -74,8 +61,8 @@ Replace its contents with this but adapt the URLs to be the ones you determined }, "icrc1_ledger_canister": { "type": "custom", - "candid": "https://raw.githubusercontent.com/dfinity/ic/d87954601e4b22972899e9957e800406a0a6b929/rs/rosetta-api/icrc1/ledger/ledger.did", - "wasm": "https://download.dfinity.systems/ic/d87954601e4b22972899e9957e800406a0a6b929/canisters/ic-icrc1-ledger.wasm.gz", + "candid": "https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icrc1/ledger/ledger.did", + "wasm": "https://download.dfinity.systems/ic//canisters/ic-icrc1-ledger.wasm.gz", "specified_id": "mxzaz-hqaaa-aaaar-qaada-cai" } }, @@ -99,13 +86,13 @@ If you chose to download the ICRC-1 ledger files with the script, you need to re ... ``` -### Step 4: Start a local replica: +## Step 4: Start a local instance of the Internet Computer ```bash dfx start --background --clean ``` -### Step 5: Create a new identity that will work as a minting account: +## Step 5: Create a new identity that will work as a minting account ```bash dfx identity new minter --storage-mode plaintext @@ -113,20 +100,22 @@ dfx identity use minter export MINTER=$(dfx identity get-principal) ``` -:::info +:::info Transfers from the minting account will create Mint transactions. Transfers to the minting account will create Burn transactions. ::: -### Step 6: Switch back to your default identity and record its principal to mint an initial balance to when deploying the ledger: +## Step 6: Switch back to your default identity + +Record its principal to mint an initial balance to when deploying the ledger: ```bash dfx identity use default export DEFAULT=$(dfx identity get-principal) ``` -### Step 7: Deploy the ICRC-1 ledger locally: +## Step 7: Deploy the ICRC-1 ledger locally Take a moment to read the details of the call made below. Not only are you deploying an ICRC-1 ledger canister, you are also: @@ -162,11 +151,10 @@ URLs: icrc1_ledger_canister: http://127.0.0.1:4943/?canisterId=bnz7o-iuaaa-aaaaa-qaaaa-cai&id=mxzaz-hqaaa-aaaar-qaada-cai ``` -### Step 8: Verify that the ledger canister is healthy and working as expected by using the command: +## Step 8: Verify that the ledger canister is healthy and working as expected -:::info - -You can find more information on how to [interact with the ICRC-1 ledger](https://internetcomputer.org/docs/current/developer-docs/defi/icrc-1/using-icrc1-ledger#icrc-1-and-icrc-1-extension-endpoints) +> [!TIP] +> You can find more information on how to [interact with the ICRC-1 ledger](https://internetcomputer.org/docs/current/developer-docs/defi/icrc-1/using-icrc1-ledger#icrc-1-and-icrc-1-extension-endpoints) ````bash dfx canister call icrc1_ledger_canister icrc1_balance_of "(record { @@ -181,7 +169,7 @@ The output should be: (10_000_000_000 : nat) ```` -### Step 9: Prepare the token transfer canister: +## Step 9: Prepare the token transfer canister Replace the contents of the `src/token_transfer_backend/Cargo.toml` file with the following: @@ -271,11 +259,8 @@ ic_cdk::export_candid!(); Replace the contents of the `src/token_transfer_backend/token_transfer_backend.did` file with the following: -:::info - -The `token_transfer_backend.did` file is a Candid file that describes the service interface of the canister. It was generated from the Rust code using the `candid-extractor` tool. You can read more about the [necessary steps](https://internetcomputer.org/docs/current/developer-docs/backend/rust/generating-candid). - -::: +> [!TIP] +> The `token_transfer_backend.did` file is a Candid file that describes the service interface of the canister. It was generated from the Rust code using the `candid-extractor` tool. You can read more about the [necessary steps](https://internetcomputer.org/docs/current/developer-docs/backend/rust/generating-candid). ```did type Account = record { owner : principal; subaccount : opt vec nat8 }; @@ -285,19 +270,16 @@ service : { transfer : (TransferArgs) -> (Result) } ``` -### Step 10: Deploy the token transfer canister: +## Step 10: Deploy the token transfer canister ```bash dfx deploy token_transfer_backend ``` -### Step 11: Transfer funds to your canister: - -:::info +## Step 11: Transfer funds to your canister -Make sure that you are using the default `dfx` account that we minted tokens to in step 7 for the following steps. - -::: +> [!WARNING] +> Make sure that you are using the default `dfx` account that we minted tokens to in step 7 for the following steps. Make the following call to transfer 10 tokens to the canister: @@ -316,7 +298,7 @@ If successful, the output should be: (variant { Ok = 1 : nat }) ``` -### Step 12: Transfer funds from the canister: +## Step 12: Transfer funds from the canister Now that the canister owns tokens on the ledger, you can transfer 1 token from the canister to another account, in this case back to the default account: diff --git a/rust/token_transfer_from/README.md b/rust/token_transfer_from/README.md index 5ebc7dea1..d17b8f3a7 100644 --- a/rust/token_transfer_from/README.md +++ b/rust/token_transfer_from/README.md @@ -1,9 +1,5 @@ # Token transfer_from -[View this samples code on GitHub](https://github.com/dfinity/examples/tree/master/rust/token_transfer_from). - -## Overview - `token_transfer_from_backend` is a canister that can transfer ICRC-1 tokens on behalf of accounts to other accounts. It is an example of a canister that uses an ICRC-1 ledger canister that supports the [ICRC-2](https://github.com/dfinity/ICRC-1/tree/main/standards/ICRC-2) approve and transfer from standard. Sample code is available in [Motoko](https://github.com/dfinity/examples/tree/master/motoko/token_transfer_from) and [Rust](https://github.com/dfinity/examples/tree/master/rust/token_transfer_from). ## Architecture @@ -16,27 +12,17 @@ This sample will use the Rust variant. This example requires an installation of: -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). -- [x] Download and install [git.](https://git-scm.com/downloads) +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -## How to get there - -The following steps will guide you through the process of setting up the token transfer canister for your own project. - -:::info - -If you just want to interact with this example, follow steps 4-6 and 8-10 below. - -::: - -### Step 1: Create a new `dfx` project and navigate into the project's directory. +## Step 1: Create a new `dfx` project and navigate into the project's directory ```bash dfx new --type=rust token_transfer_from --no-frontend cd token_transfer_from ``` -### Step 2: Determine ICRC-1 ledger file locations +## Step 2: Determine ICRC-1 ledger file locations :::info @@ -44,22 +30,22 @@ You can read more about how to [setup the ICRC-1 ledger locally](https://interne ::: -Go to the [releases overview](https://dashboard.internetcomputer.org/releases) and copy the latest replica binary revision. At the time of writing, this is `d87954601e4b22972899e9957e800406a0a6b929`. +Go to the [releases overview](https://dashboard.internetcomputer.org/releases) and copy the latest replica binary revision. -The URL for the ledger Wasm module is `https://download.dfinity.systems/ic//canisters/ic-icrc1-ledger.wasm.gz`, so with the above revision it would be `https://download.dfinity.systems/ic/d87954601e4b22972899e9957e800406a0a6b929/canisters/ic-icrc1-ledger.wasm.gz`. +The URL for the ledger Wasm module is `https://download.dfinity.systems/ic//canisters/ic-icrc1-ledger.wasm.gz`. -The URL for the ledger .did file is `https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icrc1/ledger/ledger.did`, so with the above revision it would be `https://raw.githubusercontent.com/dfinity/ic/d87954601e4b22972899e9957e800406a0a6b929/rs/rosetta-api/icrc1/ledger/ledger.did`. +The URL for the ledger .did file is `https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icrc1/ledger/ledger.did`. **OPTIONAL:** If you want to make sure, you have the latest ICRC-1 ledger files you can run the following script. ```sh -curl -o download_latest_icrc1_ledger.sh "https://raw.githubusercontent.com/dfinity/ic/326df23607fc8280a047daba2d8462f1dfc57466/rs/rosetta-api/scripts/download_latest_icrc1_ledger.sh" +curl -o download_latest_icrc1_ledger.sh "https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/scripts/download_latest_icrc1_ledger.sh" chmod +x download_latest_icrc1_ledger.sh ./download_latest_icrc1_ledger.sh ``` -### Step 3: Configure the `dfx.json` file to use the ledger : +## Step 3: Configure the `dfx.json` file to use the ledger Replace its contents with this but adapt the URLs to be the ones you determined in step 2. Note that we are deploying the ICRC-1 ledger to the same canister id the ckBTC ledger uses on mainnet. This will make it easier to interact with it later. @@ -73,8 +59,8 @@ Replace its contents with this but adapt the URLs to be the ones you determined }, "icrc1_ledger_canister": { "type": "custom", - "candid": "https://raw.githubusercontent.com/dfinity/ic/d87954601e4b22972899e9957e800406a0a6b929/rs/rosetta-api/icrc1/ledger/ledger.did", - "wasm": "https://download.dfinity.systems/ic/d87954601e4b22972899e9957e800406a0a6b929/canisters/ic-icrc1-ledger.wasm.gz", + "candid": "https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icrc1/ledger/ledger.did", + "wasm": "https://download.dfinity.systems/ic//canisters/ic-icrc1-ledger.wasm.gz", "specified_id": "mxzaz-hqaaa-aaaar-qaada-cai" } }, @@ -98,19 +84,16 @@ If you chose to download the ICRC-1 ledger files with the script, you need to re ... ``` -### Step 4: Start a local replica: +## Step 4: Start a local replica ```bash dfx start --background --clean ``` -### Step 5: Deploy the ICRC-1 ledger locally: - -:::info - -Transfers from the `minting_account` will create Mint transactions. Transfers to the minting account will create Burn transactions. +## Step 5: Deploy the ICRC-1 ledger locally -::: +> [!TIP] +> Transfers from the `minting_account` will create Mint transactions. Transfers to the minting account will create Burn transactions. Take a moment to read the details of the call made below. Not only are you deploying an ICRC-1 ledger canister, you are also: @@ -159,13 +142,10 @@ URLs: icrc1_ledger_canister: http://127.0.0.1:4943/?canisterId=bnz7o-iuaaa-aaaaa-qaaaa-cai&id=mxzaz-hqaaa-aaaar-qaada-cai ``` -### Step 6: Verify that the ledger canister is healthy and working as expected by using the command: +## Step 6: Verify that the ledger canister is healthy and working as expected -:::info - -You can find more information on how to [interact with the ICRC-1 ledger](https://internetcomputer.org/docs/current/developer-docs/defi/icrc-1/using-icrc1-ledger#icrc-1-and-icrc-1-extension-endpoints) - -::: +> [!TIP] +> You can find more information on how to [interact with the ICRC-1 ledger](https://internetcomputer.org/docs/current/developer-docs/defi/icrc-1/using-icrc1-ledger#icrc-1-and-icrc-1-extension-endpoints) ````bash dfx canister call icrc1_ledger_canister icrc1_balance_of "(record { @@ -179,7 +159,7 @@ The output should be: (10_000_000_000 : nat) ```` -### Step 7: Prepare the token transfer canister: +## Step 7: Prepare the token transfer canister Replace the contents of the `src/token_transfer_from_backend/Cargo.toml` file with the following: @@ -271,11 +251,8 @@ ic_cdk::export_candid!(); Replace the contents of the `src/token_transfer_from_backend/token_transfer_from_backend.did` file with the following: -:::info - -The `token_transfer_from.did` file is a Candid file that describes the service interface of the canister. It was generated from the Rust code using the `candid-extractor` tool. You can read more about the [necessary steps](https://internetcomputer.org/docs/current/developer-docs/backend/rust/generating-candid). - -::: +> [!TIP] +> The `token_transfer_from.did` file is a Candid file that describes the service interface of the canister. It was generated from the Rust code using the `candid-extractor` tool. You can read more about the [necessary steps](https://internetcomputer.org/docs/current/developer-docs/backend/rust/generating-candid). ```did type Account = record { owner : principal; subaccount : opt blob }; @@ -284,19 +261,16 @@ type TransferArgs = record { to_account : Account; amount : nat }; service : { transfer : (TransferArgs) -> (Result) } ``` -### Step 8: Deploy the token transfer canister: +## Step 8: Deploy the token transfer canister ```bash dfx deploy token_transfer_from_backend ``` -### Step 9: Approve the canister to transfer funds on behalf of the user: - -:::info - -Make sure that you are using the default `dfx` account that we minted tokens to in step 5 for the following steps. +## Step 9: Approve the canister to transfer funds on behalf of the user -::: +> [!TIP] +> Make sure that you are using the default `dfx` account that we minted tokens to in step 5 for the following steps. Make the following call to approve the `token_transfer_from_backend` canister to transfer 100 tokens on behalf of the `default` identity: @@ -317,7 +291,7 @@ If successful, the output should be: (variant { Ok = 1 : nat }) ``` -### Step 10: Let the canister transfer funds on behalf of the user: +## Step 10: Let the canister transfer funds on behalf of the user Now that the canister has an approval for the `default` identities tokens on the ledger, the canister can transfer 1 token on behalf of the `default` identity to another account, in this case to the canisters own account. diff --git a/rust/vetkd/README.md b/rust/vetkd/README.md index 470f68444..0e4da00fb 100644 --- a/rust/vetkd/README.md +++ b/rust/vetkd/README.md @@ -1,43 +1,43 @@ ---- -keywords: [advanced, rust, vetkeys, vetkd] ---- - # vetKD API -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/vetkd) - This repository provides a canister (`src/system_api`) that offers the vetKD system API proposed in https://github.com/dfinity/interface-spec/pull/158, implemented in an **unsafe** manner **for demonstration purposes**. Additionally, the repository provides: + * An example app backend canister (`src/app_backend`) implemented in **Rust** that makes use of this system API to provide caller-specific symmetric keys that can be used for AES encryption and decryption. * An example frontend (`src/app_frontend_js`) that uses the backend from Javascript in the browser. The frontend uses the [ic-vetkd-utils](https://github.com/dfinity/ic/tree/master/packages/ic-vetkd-utils) to create a transport key pair that is used to obtain a verifiably encrypted key from the system API, to decrypt this key, and to derive a symmetric key to be used for AES encryption/decryption. - + Because the `ic-vetkd-utils` are not yet published as NPM package at [npmjs.com](https://npmjs.com), a respective package file (`ic-vetkd-utils-0.1.0.tgz`) is included in this repository. +--- + ## Disclaimer The implementation of [the proposed vetKD system API](https://github.com/dfinity/interface-spec/pull/158) used in this example is **unsafe**, e.g., we hard-code a master secret key, rather than using a master secret key that is distributed among sufficiently many Internet Computer nodes through distributed key generation. **Do not use this in production or for sensitive data**! This example is solely provided **for demonstration purposes** to collect feedback on the mentioned vetKD system API. See also the respective disclaimer [in the system API canister implementation](https://github.com/dfinity/examples/blob/master/rust/vetkd/src/system_api/src/lib.rs#L19-L26). +--- + ## Prerequisites -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/). +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` - [x] Install [Node.js](https://nodejs.org/en/download/). - [x] Install [Rust](https://www.rust-lang.org/tools/install), and add Wasm as a target (`rustup target add wasm32-unknown-unknown`). -- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -## Running Locally +## Step 1: Setup project environment -- #### Step 1: Start a local internet computer. +Navigate into the folder containing the project's files and start a local instance of the replica with the command: ```sh -dfx start +cd examples/rust/vetkd +dfx start --clean ``` -- #### Step 2: Open a new terminal window. +## Step 2: Open a new terminal window. -- #### Step 3: Ensure `dfx` uses the canister IDs that are hard-coded in the Rust source code: +## Step 3: Ensure `dfx` uses the canister IDs that are hard-coded in the Rust source code: ```sh cd examples/rust/vetkd @@ -46,13 +46,13 @@ dfx canister create system_api --specified-id s55qq-oqaaa-aaaaa-aaakq-cai Without this, the `dfx` may use different canister IDs for the `system_api` and `app_backend` canisters in your local environment. -- #### Step 4: Ensure that the required node modules are available in your project directory, if needed, by running the following command: +## Step 4: Ensure that the required node modules are available in your project directory, if needed, by running the following command: ```sh npm install ``` -- #### Step 5:. Register, build, and deploy the project: +## Step 5:. Register, build, and deploy the project: ```sh dfx deploy @@ -71,4 +71,4 @@ Backend canister via Candid interface: system_api: http://127.0.0.1:4943/?canisterId=avqkn-guaaa-aaaaa-qaaea-cai&id=s55qq-oqaaa-aaaaa-aaakq-cai ``` -- #### Step 6: Open the printed URL for the `app_frontend_js` in your browser. +## Step 6: Open the printed URL for the `app_frontend_js` in your browser. diff --git a/rust/x509/README.md b/rust/x509/README.md index 17f9fd5c4..4a6e64495 100644 --- a/rust/x509/README.md +++ b/rust/x509/README.md @@ -1,11 +1,5 @@ ---- -keywords: [advanced, rust, X.509, certificate, certificate signing request, certification authority, ed25519, threshold schnorr, schnorr, threshold ecdsa, ecdsa, secp256k1, signature] ---- - # X.509 -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/x509) - ## Overview We present a minimal example canister smart contract for showcasing two use @@ -41,19 +35,16 @@ up to the deployment and trying out the code on the mainnet. ## Prerequisites -- [x] Download and [install the IC - SDK](https://internetcomputer.org/docs/current/developer-docs/setup/index.md) - if you do not already have it.The minimum version of `dfx` that allows to - run this example locally is `0.23.0`. +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install) v`0.23.0` or newer. +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` + +The minimum version of `dfx` thatrun this example locally is - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -## Getting started +## Deploy and test the canister locally Sample code for `x509-example` is provided in the [examples repository](https://github.com/dfinity/examples), under [`/rust`](https://github.com/dfinity/examples/tree/master/rust/x509) sub-directory. -### Deploy and test the canister locally - -This tutorial will use the Rust version of the canister: ```bash cd examples/rust/x509 @@ -79,18 +70,18 @@ public methods the canister exposes. Since the canister exposes `root_ca_certificate` and `child_certificate` methods, those are rendered in the web UI. -### Deploying the canister on the mainnet +## Deploying the canister on the mainnet -To deploy this canister the mainnet, one needs to do two things: +To deploy this canister the mainnet, you must do two things: - Acquire cycles (equivalent of "gas" in other blockchains). This is necessary for all canisters. - Update the sample source code to have the right key ID. This is unique to this canister. -#### Acquire cycles to deploy +- #### Step 1: Acquire cycles to deploy Deploying to the Internet Computer requires [cycles](https://internetcomputer.org/docs/current/developer-docs/getting-started/tokens-and-cycles) (the equivalent of "gas" on other blockchains). -#### Update source code with the right key ID +- #### Step 2: Update source code with the right key ID To deploy the sample code, the canister needs the right key name for the right environment. Specifically, one needs to initialize the canister with the key @@ -104,9 +95,9 @@ There are three options that are supported: * `key_1`: a master **production** key ID that is used in mainnet. Note that `dfx deploy` formats those name in `PascalCase` instead of -`snake_case` due to the formating of types in `rust`. +`snake_case` due to the formatting of types in `rust`. -#### Deploy to the mainnet via IC SDK +- #### Step 3: Deploy to the mainnet using the IC SDK To [deploy via the mainnet](https://internetcomputer.org/docs/current/developer-docs/setup/deploy-mainnet.md), run the following commands: @@ -114,6 +105,7 @@ To [deploy via the mainnet](https://internetcomputer.org/docs/current/developer- npm install dfx deploy --network ic ``` + If successful, you should see something like this: ```bash @@ -125,7 +117,7 @@ URLs: In the example above, `x509_example_rust` has the URL https://a3gq9-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=736w4-cyaaa-aaaal-qb3wq-cai and serves up the Candid web UI for this particular canister deployed on mainnet. -## Obtaining root CA certificate +## Obtaining the root CA certificate ### Using the Candid Web UI From 918e219a3edca28575a21741279131c8f31191b2 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon Date: Thu, 19 Dec 2024 15:53:58 -0600 Subject: [PATCH 13/51] fix" " --- motoko/canister_logs/README.md | 54 ++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/motoko/canister_logs/README.md b/motoko/canister_logs/README.md index 545dd99b9..ad69e31b5 100644 --- a/motoko/canister_logs/README.md +++ b/motoko/canister_logs/README.md @@ -1,64 +1,66 @@ -# Canister logs - -## Prerequisites +--- +keywords: [beginner, motoko, canister logs, logging] +--- -- [x] Install the [IC - SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. -- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` +# Canister logs -## Step 1: Setup project environment +[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/canister_logs) -Navigate into the folder containing the project's files and start a local instance of the replica with the command: +## Prerequisites +This example requires an installation of: -```shell -dfx start --clean -``` +- [x] DFX version 0.19.0 or newer +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/). +- [x] Download the following project files from GitHub: `git clone https://github.com/dfinity/examples/` You will need to have 3 terminal windows: -- Terminal A: Running a `dfx` instance and separating its output from anything else. -- Terminal B: Deploying a canister and seeing its output. -- Terminal C: Reading logs interactively. +- Terminal A: Running a DFX instance and separating its output from anything else +- Terminal B: Deploying a canister and seeing its output +- Terminal C: Reading logs interactively + +### Step 1: Navigate into the folder containing the project's files and start a local instance of the replica with the command: ```shell # Terminal A -- for running DFX and separating its output from anything else. -cd examples/motoko/canister_logs +$ cd examples/motoko/canister_logs +$ dfx start --clean # Terminal B -- for deploying the canister and calling its methods. -cd examples/motoko/canister_logs +$ cd examples/motoko/canister_logs # Terminal C -- for polling logs. -cd examples/motoko/canister_logs +$ cd examples/motoko/canister_logs ``` -## Step 2: Deploy the canister +### Step 2: Deploy the canister: ```shell # Terminal B -dfx deploy +$ dfx deploy ``` -## Step 3: Check canister logs +### Step 3: Check canister logs: Expect to see logs from timer traps. ```shell # Terminal B -dfx canister logs CanisterLogs +$ dfx canister logs CanisterLogs [0. 2024-05-23T08:32:26.203980235Z]: right before timer trap [1. 2024-05-23T08:32:26.203980235Z]: [TRAP]: timer trap [2. 2024-05-23T08:32:31.836721763Z]: right before timer trap [3. 2024-05-23T08:32:31.836721763Z]: [TRAP]: timer trap ``` -## Step 4: Call `print` method and check the logs +### Step 4: Call `print` method and check the logs: ```shell # Terminal B -dfx canister call CanisterLogs print hi +$ dfx canister call CanisterLogs print hi () # Expect to see new log entry. -dfx canister logs CanisterLogs +$ dfx canister logs CanisterLogs ... [8. 2024-05-23T08:32:46.598972616Z]: right before timer trap [9. 2024-05-23T08:32:46.598972616Z]: [TRAP]: timer trap @@ -68,7 +70,7 @@ dfx canister logs CanisterLogs ... ``` -## Step 5: Start constantly polling logs +### Step 5: Start constantly polling logs: In order not to call `dfx canister logs CanisterLogs` after every canister call in a separate terminal window/pane C start a script that will constantly poll logs: @@ -84,7 +86,7 @@ $ ./poll_logs.sh ... ``` -## Step 6: Call `print`, `trap` and other canister methods +### Step 6: Call `print`, `trap` and other canister methods: ```shell # Terminal B From cb799f8cb339ae61b066e415729a975c4f25a856 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:57:30 -0600 Subject: [PATCH 14/51] Apply suggestions from code review --- motoko/canister_logs/README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/motoko/canister_logs/README.md b/motoko/canister_logs/README.md index 32e3da531..79fb84773 100644 --- a/motoko/canister_logs/README.md +++ b/motoko/canister_logs/README.md @@ -43,7 +43,7 @@ Expect to see logs from timer traps. ```shell # Terminal B -dfx canister logs CanisterLogs +$ dfx canister logs CanisterLogs [0. 2024-05-23T08:32:26.203980235Z]: right before timer trap [1. 2024-05-23T08:32:26.203980235Z]: [TRAP]: timer trap [2. 2024-05-23T08:32:31.836721763Z]: right before timer trap @@ -54,11 +54,11 @@ dfx canister logs CanisterLogs ```shell # Terminal B -dfx canister call CanisterLogs print hi +$ dfx canister call CanisterLogs print hi () # Expect to see new log entry. -dfx canister logs CanisterLogs +$ dfx canister logs CanisterLogs ... [8. 2024-05-23T08:32:46.598972616Z]: right before timer trap [9. 2024-05-23T08:32:46.598972616Z]: [TRAP]: timer trap @@ -88,21 +88,21 @@ $ ./poll_logs.sh ```shell # Terminal B -dfx canister call CanisterLogs print hi! +$ dfx canister call CanisterLogs print hi! () -dfx canister call CanisterLogs print hello! +$ dfx canister call CanisterLogs print hello! () -dfx canister call CanisterLogs print yey! +$ dfx canister call CanisterLogs print yey! () -dfx canister call CanisterLogs trap oops! +$ dfx canister call CanisterLogs trap oops! Error: Failed update call. Caused by: Failed update call. The replica returned a rejection error: reject code CanisterError, reject message Canister bkyz2-fmaaa-aaaaa-qaaaq-cai trapped explicitly: oops!, error code None -dfx canister call CanisterLogs memory_oob +$ dfx canister call CanisterLogs memory_oob Error: Failed update call. Caused by: Failed update call. The replica returned a rejection error: reject code CanisterError, reject message Canister bkyz2-fmaaa-aaaaa-qaaaq-cai trapped explicitly: StableMemory range out of bounds, error code None From 34ec5796fc9ec18b9a18eba5d68f30b3e43e84a9 Mon Sep 17 00:00:00 2001 From: Oleksandr Tkachenko <108659113+altkdf@users.noreply.github.com> Date: Fri, 3 Jan 2025 17:13:42 +0100 Subject: [PATCH 15/51] add BIP341 to the threshold Schnorr rust example (#1071) --- .../rust-threshold-schnorr-example.yml | 4 +- rust/threshold-schnorr/Cargo.lock | 557 ++++++++++++------ rust/threshold-schnorr/Makefile | 9 + rust/threshold-schnorr/README.md | 144 ++++- rust/threshold-schnorr/dfx.json | 9 +- .../src/schnorr_example_rust/Cargo.toml | 7 +- .../src/schnorr_example_rust/build.sh | 21 + .../schnorr_example_rust/schnorr_example.did | 5 +- .../src/all_architectures.rs | 4 +- .../src/schnorr_example_rust/src/wasm_only.rs | 157 ++++- .../src/schnorr_example_rust/tests/tests.rs | 120 +++- 11 files changed, 802 insertions(+), 235 deletions(-) create mode 100755 rust/threshold-schnorr/src/schnorr_example_rust/build.sh diff --git a/.github/workflows/rust-threshold-schnorr-example.yml b/.github/workflows/rust-threshold-schnorr-example.yml index d01ee8734..829993779 100644 --- a/.github/workflows/rust-threshold-schnorr-example.yml +++ b/.github/workflows/rust-threshold-schnorr-example.yml @@ -20,7 +20,9 @@ jobs: steps: - uses: actions/checkout@v1 - name: Provision Darwin - run: bash .github/workflows/provision-darwin.sh + run: | + bash .github/workflows/provision-darwin.sh + brew install llvm - name: Provision PocketIC run: bash .github/workflows/provision-pocket-ic-server.sh - name: Rust Threshold Schnorr Darwin diff --git a/rust/threshold-schnorr/Cargo.lock b/rust/threshold-schnorr/Cargo.lock index 0dc873c73..c35a28fe9 100644 --- a/rust/threshold-schnorr/Cargo.lock +++ b/rust/threshold-schnorr/Cargo.lock @@ -38,6 +38,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + [[package]] name = "atomic-waker" version = "1.1.2" @@ -66,10 +72,14 @@ dependencies = [ ] [[package]] -name = "base16ct" -version = "0.2.0" +name = "base58ck" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +checksum = "2c8d66485a3a2ea485c1913c4572ce0256067a5377ac8c75c4960e1cda98605f" +dependencies = [ + "bitcoin-internals", + "bitcoin_hashes", +] [[package]] name = "base64" @@ -89,6 +99,12 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "bech32" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d" + [[package]] name = "binread" version = "2.2.0" @@ -112,6 +128,54 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "bitcoin" +version = "0.32.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6bc65742dea50536e35ad42492b234c27904a27f0abdcbce605015cb4ea026" +dependencies = [ + "base58ck", + "bech32", + "bitcoin-internals", + "bitcoin-io", + "bitcoin-units", + "bitcoin_hashes", + "hex-conservative", + "hex_lit", + "secp256k1", +] + +[[package]] +name = "bitcoin-internals" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30bdbe14aa07b06e6cfeffc529a1f099e5fbe249524f8125358604df99a4bed2" + +[[package]] +name = "bitcoin-io" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b47c4ab7a93edb0c7198c5535ed9b52b63095f4e9b45279c6736cec4b856baf" + +[[package]] +name = "bitcoin-units" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5285c8bcaa25876d07f37e3d30c303f2609179716e11d688f51e8f1fe70063e2" +dependencies = [ + "bitcoin-internals", +] + +[[package]] +name = "bitcoin_hashes" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16" +dependencies = [ + "bitcoin-io", + "hex-conservative", +] + [[package]] name = "bitflags" version = "2.5.0" @@ -147,9 +211,9 @@ checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "candid" -version = "0.10.4" +version = "0.10.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd70c7bed52cb20e38dd933c19c0c9abf0302b60db3fa3186e27ec53edf6ad" +checksum = "d04aa85a9ba2542bded33d1eff0ffb17cb98b1be8117e0a25e1ad8c62bedc881" dependencies = [ "anyhow", "binread", @@ -177,7 +241,7 @@ dependencies = [ "lazy_static", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.90", ] [[package]] @@ -250,18 +314,6 @@ version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" -[[package]] -name = "crypto-bigint" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" -dependencies = [ - "generic-array", - "rand_core", - "subtle", - "zeroize", -] - [[package]] name = "crypto-common" version = "0.1.6" @@ -296,7 +348,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.90", ] [[package]] @@ -331,9 +383,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", - "const-oid", "crypto-common", - "subtle", ] [[package]] @@ -342,20 +392,6 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" -[[package]] -name = "ecdsa" -version = "0.16.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" -dependencies = [ - "der", - "digest", - "elliptic-curve", - "rfc6979", - "signature", - "spki", -] - [[package]] name = "ed25519" version = "2.2.3" @@ -387,22 +423,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] -name = "elliptic-curve" -version = "0.13.8" +name = "encoding_rs" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ - "base16ct", - "crypto-bigint", - "digest", - "ff", - "generic-array", - "group", - "pkcs8", - "rand_core", - "sec1", - "subtle", - "zeroize", + "cfg-if", ] [[package]] @@ -421,15 +447,21 @@ dependencies = [ ] [[package]] -name = "ff" -version = "0.13.0" +name = "errno" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ - "rand_core", - "subtle", + "libc", + "windows-sys 0.59.0", ] +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + [[package]] name = "fiat-crypto" version = "0.2.7" @@ -452,6 +484,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -491,7 +538,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.90", ] [[package]] @@ -531,7 +578,6 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", - "zeroize", ] [[package]] @@ -551,17 +597,6 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" -[[package]] -name = "group" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff", - "rand_core", - "subtle", -] - [[package]] name = "h2" version = "0.4.5" @@ -581,12 +616,24 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" + [[package]] name = "hashbrown" version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.3.9" @@ -603,14 +650,20 @@ dependencies = [ ] [[package]] -name = "hmac" -version = "0.12.1" +name = "hex-conservative" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +checksum = "5313b072ce3c597065a808dbf612c4c8e8590bdbf8b579508bf7a762c5eae6cd" dependencies = [ - "digest", + "arrayvec 0.7.6", ] +[[package]] +name = "hex_lit" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd" + [[package]] name = "http" version = "1.1.0" @@ -690,6 +743,22 @@ dependencies = [ "webpki-roots", ] +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + [[package]] name = "hyper-util" version = "0.1.5" @@ -710,19 +779,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "ic-cdk" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b1da6a25b045f9da3c9459c0cb2b0700ac368ee16382975a17185a23b9c18ab" -dependencies = [ - "candid", - "ic-cdk-macros 0.13.2", - "ic0 0.21.1", - "serde", - "serde_bytes", -] - [[package]] name = "ic-cdk" version = "0.16.0" @@ -730,45 +786,54 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8ecacd682fa05a985253592963306cb9799622d7b1cce4b1edb89c6ec85be1" dependencies = [ "candid", - "ic-cdk-macros 0.16.0", - "ic0 0.23.0", + "ic-cdk-macros", + "ic0", "serde", "serde_bytes", ] [[package]] name = "ic-cdk-macros" -version = "0.13.2" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a45800053d80a6df839a71aaea5797e723188c0b992618208ca3b941350c7355" +checksum = "0d4d857135deef20cc7ea8f3869a30cd9cfeb1392b3a81043790b2cd82adc3e0" dependencies = [ "candid", "proc-macro2", "quote", "serde", - "serde_tokenstream 0.1.7", - "syn 1.0.109", + "serde_tokenstream", + "syn 2.0.90", ] [[package]] -name = "ic-cdk-macros" -version = "0.16.0" +name = "ic-certification" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4d857135deef20cc7ea8f3869a30cd9cfeb1392b3a81043790b2cd82adc3e0" +checksum = "e64ee3d8b6e81b51f245716d3e0badb63c283c00f3c9fb5d5219afc30b5bf821" dependencies = [ - "candid", - "proc-macro2", - "quote", + "hex", "serde", - "serde_tokenstream 0.2.2", - "syn 2.0.48", + "serde_bytes", + "sha2", ] [[package]] -name = "ic0" -version = "0.21.1" +name = "ic-transport-types" +version = "0.37.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a54b5297861c651551676e8c43df805dad175cc33bc97dbd992edbbb85dcbcdf" +checksum = "875dc4704780383112e8e8b5063a1b98de114321d0c7d3e7f635dcf360a57fba" +dependencies = [ + "candid", + "hex", + "ic-certification", + "leb128", + "serde", + "serde_bytes", + "serde_repr", + "sha2", + "thiserror", +] [[package]] name = "ic0" @@ -830,19 +895,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "k256" -version = "0.13.3" -source = "git+https://github.com/altkdf/elliptic-curves?branch=schnorr_canister#01d6e705afb663487cf61226e087c6874fac72a0" -dependencies = [ - "cfg-if", - "ecdsa", - "elliptic-curve", - "once_cell", - "sha2", - "signature", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -861,6 +913,12 @@ version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + [[package]] name = "lock_api" version = "0.4.12" @@ -929,6 +987,23 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "native-tls" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -991,12 +1066,50 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "openssl" +version = "0.10.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "openssl-sys" +version = "0.9.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "overload" version = "0.1.1" @@ -1055,7 +1168,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.90", ] [[package]] @@ -1080,27 +1193,39 @@ dependencies = [ "spki", ] +[[package]] +name = "pkg-config" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + [[package]] name = "pocket-ic" -version = "5.0.0" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beff607d4dbebff8d003453ced669d2645e905de496ca93713f3d47633357e6c" +checksum = "124a2380ca6f557adf8b02517cbfd2f564113230e14cda6f6aadd3dfe156293c" dependencies = [ "base64 0.13.1", "candid", "hex", - "ic-cdk 0.13.5", + "ic-certification", + "ic-transport-types", "reqwest", "schemars", "serde", "serde_bytes", + "serde_cbor", "serde_json", "sha2", "slog", + "strum", + "strum_macros", + "thiserror", "tokio", "tracing", "tracing-appender", "tracing-subscriber", + "wslpath", ] [[package]] @@ -1124,16 +1249,16 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b55c4d17d994b637e2f4daf6e5dc5d660d209d5642377d675d7a1c3ab69fa579" dependencies = [ - "arrayvec", + "arrayvec 0.5.2", "typed-arena", "unicode-width", ] [[package]] name = "proc-macro2" -version = "1.0.76" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -1295,6 +1420,7 @@ checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b" dependencies = [ "base64 0.22.1", "bytes", + "encoding_rs", "futures-channel", "futures-core", "futures-util", @@ -1304,12 +1430,14 @@ dependencies = [ "http-body-util", "hyper", "hyper-rustls", + "hyper-tls", "hyper-util", "ipnet", "js-sys", "log", "mime", "mime_guess", + "native-tls", "once_cell", "percent-encoding", "pin-project-lite", @@ -1322,7 +1450,9 @@ dependencies = [ "serde_json", "serde_urlencoded", "sync_wrapper", + "system-configuration", "tokio", + "tokio-native-tls", "tokio-rustls", "tokio-socks", "tokio-util", @@ -1336,16 +1466,6 @@ dependencies = [ "windows-registry", ] -[[package]] -name = "rfc6979" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" -dependencies = [ - "hmac", - "subtle", -] - [[package]] name = "ring" version = "0.17.8" @@ -1382,6 +1502,19 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.38.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + [[package]] name = "rustls" version = "0.23.13" @@ -1485,14 +1618,15 @@ dependencies = [ name = "schnorr_example_rust" version = "0.1.0" dependencies = [ + "bitcoin", "candid", "ed25519-dalek", "flate2", "getrandom", "hex", - "ic-cdk 0.16.0", - "k256", + "ic-cdk", "pocket-ic", + "reqwest", "serde", "serde_bytes", "sha2", @@ -1505,17 +1639,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] -name = "sec1" -version = "0.7.3" +name = "secp256k1" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113" dependencies = [ - "base16ct", - "der", - "generic-array", - "pkcs8", - "subtle", - "zeroize", + "bitcoin_hashes", + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9" +dependencies = [ + "cc", ] [[package]] @@ -1565,6 +1704,16 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half", + "serde", +] + [[package]] name = "serde_derive" version = "1.0.204" @@ -1573,7 +1722,7 @@ checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.90", ] [[package]] @@ -1599,14 +1748,14 @@ dependencies = [ ] [[package]] -name = "serde_tokenstream" -version = "0.1.7" +name = "serde_repr" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "797ba1d80299b264f3aac68ab5d12e5825a561749db4df7cd7c8083900c5d4e9" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", - "serde", - "syn 1.0.109", + "quote", + "syn 2.0.90", ] [[package]] @@ -1618,7 +1767,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.48", + "syn 2.0.90", ] [[package]] @@ -1667,10 +1816,6 @@ name = "signature" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fe458c98333f9c8152221191a77e2a44e8325d0193484af2e9421a53019e57d" -dependencies = [ - "digest", - "rand_core", -] [[package]] name = "slab" @@ -1735,6 +1880,28 @@ dependencies = [ "winapi", ] +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.90", +] + [[package]] name = "subtle" version = "2.5.0" @@ -1754,9 +1921,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -1772,24 +1939,58 @@ dependencies = [ "futures-core", ] +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +dependencies = [ + "cfg-if", + "fastrand", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.90", ] [[package]] @@ -1850,9 +2051,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.40.0" +version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" dependencies = [ "backtrace", "bytes", @@ -1874,7 +2075,17 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.90", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", ] [[package]] @@ -1972,7 +2183,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.90", ] [[package]] @@ -2104,6 +2315,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" @@ -2146,7 +2363,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.90", "wasm-bindgen-shared", ] @@ -2180,7 +2397,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2357,6 +2574,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "wslpath" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04a2ecdf2cc4d33a6a93d71bcfbc00bb1f635cdb8029a2cc0709204a045ec7a3" + [[package]] name = "zerocopy" version = "0.7.35" @@ -2375,7 +2598,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.90", ] [[package]] diff --git a/rust/threshold-schnorr/Makefile b/rust/threshold-schnorr/Makefile index c277d4a9e..83a15d8e4 100644 --- a/rust/threshold-schnorr/Makefile +++ b/rust/threshold-schnorr/Makefile @@ -11,6 +11,15 @@ build: deploy: dfx deploy +.PHONY: mock +.SILENT: mock +mock: deploy + SCHNORR_MOCK_CANISTER_ID=$(shell dfx canister id chainkey_testing_canister); \ + SCHNORR_EXAMPLE_CANISTER_ID=$(shell dfx canister id schnorr_example_rust); \ + echo "Changing to using mock canister instead of management canister for signing"; \ + CMD="dfx canister call "$${SCHNORR_EXAMPLE_CANISTER_ID}" for_test_only_change_management_canister_id '("\"$${SCHNORR_MOCK_CANISTER_ID}\"")'"; \ + eval "$${CMD}" + .PHONY: test .SILENT: test test: build diff --git a/rust/threshold-schnorr/README.md b/rust/threshold-schnorr/README.md index 11ef6b1ca..bd35b7ac8 100644 --- a/rust/threshold-schnorr/README.md +++ b/rust/threshold-schnorr/README.md @@ -14,8 +14,8 @@ Schnorr](https://internetcomputer.org/docs/current/references/ic-interface-spec/ API. The example canister is a signing oracle that creates Schnorr signatures with -keys derived based on the canister ID and the chosen algorithm, either BIP340 or -Ed25519. +keys derived based on the canister ID and the chosen algorithm, either +BIP340/BIP341 or Ed25519. More specifically: @@ -40,6 +40,7 @@ version available in the same repo and follows the same commands for deploying. if you do not already have it. For local testing, `dfx >= 0.22.0-beta.0` is required. - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` +- [x] On macOS, llvm with the `wasm32-unknown-unknown` target (which is not included in the XCode installation by default) is required. To install, run `brew install llvm`. ## Getting started @@ -83,12 +84,30 @@ To deploy this canister the mainnet, one needs to do two things: Deploying to the Internet Computer requires [cycles](https://internetcomputer.org/docs/current/developer-docs/getting-started/tokens-and-cycles) (the equivalent of "gas" on other blockchains). +#### Update management canister ID reference for testing + +The latest version of `dfx`, `v0.24.3`, does not yet support +`opt_merkle_tree_root_hex` that is not `None`. Therefore, for local tests, [the +chain-key testing canister](https://github.com/dfinity/chainkey-testing-canister) +can be installed and used instead of the management canister. Note also that the +chain-key testing canister is deployed on the mainnet and can be used for mainnet +testing to reduce the costs, see the linked repo for more details. + +This sample canister allows the caller to change the management canister address +for Schnorr by calling the `for_test_only_change_management_canister_id` +endpoint with the target canister principal. With `dfx`, this can be done +automatically with `make mock`, which will install the chain-key testing canister +and use it instead of the management canister. Note that `dfx` should be running +to successfully run `make mock`. + #### Update source code with the right key ID To deploy the sample code, the canister needs the right key ID for the right environment. Specifically, one needs to replace the value of the `key_id` in the `src/schnorr_example_rust/src/lib.rs` file of the sample code. Before deploying to mainnet, one should modify the code to use the right name of the `key_id`. -There are three options that are planed to be supported: +There are four options that are planed to be supported: +* `insecure_test_key_1`: the key ID supported by the `chainkey_testing_canister` + ([link](https://github.com/dfinity/chainkey-testing-canister/)). * `dfx_test_key`: a default key ID that is used in deploying to a local version of IC (via IC SDK). * `test_key_1`: a master **test** key ID that is used in mainnet. * `key_1`: a master **production** key ID that is used in mainnet. @@ -96,14 +115,15 @@ There are three options that are planed to be supported: For example, the default code in `src/schnorr_example_rust/src/lib.rs` derives the key ID as follows and can be deployed locally: ```rust -SchnorrKeyIds::TestKeyLocalDevelopment.to_key_id(algorithm) +SchnorrKeyIds::ChainkeyTestingCanisterKey1.to_key_id(algorithm) ``` IMPORTANT: To deploy to IC mainnet, one needs to replace -`SchnorrKeyIds::TestKeyLocalDevelopment` (which maps to the `"dfx_test_key"` key -id) with either `SchnorrKeyIds::TestKey1` (`"test_key_1"`) or -`SchnorrKeyIds::ProductionKey1` (`"key_1"`) depending on the desired intent. -Both uses of key ID in `src/schnorr_example_rust/src/lib.rs` must be consistent. +`SchnorrKeyIds::ChainkeyTestingCanisterKey1` (which maps to the +`"insecure_test_key_1"` key id) with either `SchnorrKeyIds::TestKey1` +(`"test_key_1"`) or `SchnorrKeyIds::ProductionKey1` (`"key_1"`) depending on the +desired intent. Both uses of key ID in `src/schnorr_example_rust/src/lib.rs` +must be consistent. #### Deploy to the mainnet via IC SDK @@ -153,11 +173,11 @@ async fn public_key(algorithm: SchnorrAlgorithm) -> Result Result { +async fn sign( + message: String, + algorithm: SchnorrAlgorithm, + opt_merkle_tree_root_hex: Option, +) -> Result { + let aux = opt_merkle_tree_root_hex + .map(|hex| { + hex::decode(&hex) + .map_err(|e| format!("failed to decode hex: {e:?}")) + .and_then(|bytes| { + if bytes.len() == 32 || bytes.is_empty() { + Ok(SignWithSchnorrAux::Bip341(SignWithBip341Aux { + merkle_root_hash: ByteBuf::from(bytes), + })) + } else { + Err(format!( + "merkle tree root bytes must be 0 or 32 bytes long but got {}", + bytes.len() + )) + } + }) + }) + .transpose()?; + let internal_request = ManagementCanisterSignatureRequest { message: message.as_bytes().to_vec(), derivation_path: vec![ic_cdk::api::caller().as_slice().to_vec()], - key_id: SchnorrKeyIds::TestKeyLocalDevelopment.to_key_id(algorithm), + key_id: SchnorrKeyIds::ChainkeyTestingCanisterKey1.to_key_id(algorithm), + aux, }; let (internal_reply,): (ManagementCanisterSignatureReply,) = ic_cdk::api::call::call_with_payment( - Principal::management_canister(), + mgmt_canister_id(), "sign_with_schnorr", (internal_request,), - 25_000_000_000, + 26_153_846_153, ) .await .map_err(|e| format!("sign_with_schnorr failed {e:?}"))?; @@ -229,6 +286,7 @@ async fn verify( signature_hex: String, message: String, public_key_hex: String, + opt_merkle_tree_root_hex: Option, algorithm: SchnorrAlgorithm, ) -> Result { let sig_bytes = hex::decode(&signature_hex).expect("failed to hex-decode signature"); @@ -236,10 +294,20 @@ async fn verify( let pk_bytes = hex::decode(&public_key_hex).expect("failed to hex-decode public key"); match algorithm { - SchnorrAlgorithm::Bip340Secp256k1 => { - verify_bip340_secp256k1(&sig_bytes, msg_bytes, &pk_bytes) + SchnorrAlgorithm::Bip340Secp256k1 => match opt_merkle_tree_root_hex { + Some(merkle_tree_root_hex) => { + let merkle_tree_root_bytes = hex::decode(&merkle_tree_root_hex) + .expect("failed to hex-decode merkle tree root"); + verify_bip341_secp256k1(&sig_bytes, msg_bytes, &pk_bytes, &merkle_tree_root_bytes) + } + None => verify_bip340_secp256k1(&sig_bytes, msg_bytes, &pk_bytes), + }, + SchnorrAlgorithm::Ed25519 => { + if let Some(_) = opt_merkle_tree_root_hex { + return Err("ed25519 does not support merkle tree root verification".to_string()); + } + verify_ed25519(&sig_bytes, &msg_bytes, &pk_bytes) } - SchnorrAlgorithm::Ed25519 => verify_ed25519(&sig_bytes, &msg_bytes, &pk_bytes), } } @@ -262,6 +330,43 @@ fn verify_bip340_secp256k1( Ok(SignatureVerificationReply { is_signature_valid }) } +fn verify_bip341_secp256k1( + sig_bytes: &[u8], + msg_bytes: &[u8], + secp1_pk_bytes: &[u8], + merkle_tree_root_bytes: &[u8], +) -> Result { + assert_eq!(secp1_pk_bytes.len(), 33); + + let pk = XOnlyPublicKey::from_slice(&secp1_pk_bytes[1..]).unwrap(); + let tweaked_pk_bytes = { + let secp256k1_engine = Secp256k1::new(); + let merkle_root = if merkle_tree_root_bytes.len() == 0 { + None + } else { + Some( + bitcoin::hashes::Hash::from_slice(&merkle_tree_root_bytes) + .expect("failed to create TapBranchHash"), + ) + }; + + pk.tap_tweak(&secp256k1_engine, merkle_root) + .0 + .to_inner() + .serialize() + }; + + let sig = + k256::schnorr::Signature::try_from(sig_bytes).expect("failed to deserialize signature"); + + let vk = k256::schnorr::VerifyingKey::from_bytes(&tweaked_pk_bytes) + .expect("failed to deserialize BIP340 encoding into public key"); + + let is_signature_valid = vk.verify_raw(&msg_bytes, &sig).is_ok(); + + Ok(SignatureVerificationReply { is_signature_valid }) +} + fn verify_ed25519( sig_bytes: &[u8], msg_bytes: &[u8], @@ -288,8 +393,9 @@ and `false` or trap on errors otherwise. Similar verifications can be done in many other languages with the help of cryptographic libraries that support the `bip340secp256k1` signing *with arbitrary message length* as specified in -[BIP340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#user-content-Messages_of_Arbitrary_Size) -and `ed25519` signing. +[BIP340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#user-content-Messages_of_Arbitrary_Size)/ +[BIP341](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki) and +`ed25519` signing. ## Conclusion diff --git a/rust/threshold-schnorr/dfx.json b/rust/threshold-schnorr/dfx.json index 123a17292..4daf351bc 100644 --- a/rust/threshold-schnorr/dfx.json +++ b/rust/threshold-schnorr/dfx.json @@ -2,8 +2,15 @@ "canisters": { "schnorr_example_rust": { "candid": "src/schnorr_example_rust/schnorr_example.did", + "wasm": "target/wasm32-unknown-unknown/release/schnorr_example_rust.wasm", "package": "schnorr_example_rust", - "type": "rust" + "type": "custom", + "build": "src/schnorr_example_rust/build.sh" + }, + "chainkey_testing_canister": { + "type": "custom", + "candid": "https://github.com/dfinity/chainkey-testing-canister/releases/download/v0.1.0/chainkey_testing_canister.did", + "wasm": "https://github.com/dfinity/chainkey-testing-canister/releases/download/v0.1.0/chainkey_testing_canister.wasm.gz" } } } \ No newline at end of file diff --git a/rust/threshold-schnorr/src/schnorr_example_rust/Cargo.toml b/rust/threshold-schnorr/src/schnorr_example_rust/Cargo.toml index 25b102505..6163a2df8 100644 --- a/rust/threshold-schnorr/src/schnorr_example_rust/Cargo.toml +++ b/rust/threshold-schnorr/src/schnorr_example_rust/Cargo.toml @@ -8,16 +8,17 @@ path = "src/lib.rs" crate-type = ["lib", "cdylib"] [dependencies] -candid = "=0.10.4" +bitcoin = "0.32.5" +candid = "0.10.4" ed25519-dalek = "2.1" getrandom = { version = "0.2", features = ["custom"] } hex = "0.4" ic-cdk = "0.16" -k256 = { git = "https://github.com/altkdf/elliptic-curves", branch = "schnorr_canister", features = ["schnorr"] } sha2 = "0.10" serde = "1.0" serde_bytes = "0.11" [dev-dependencies] flate2 = "1.0" -pocket-ic = "5.0.0" +pocket-ic = "6.0.0" +reqwest = "0.12" diff --git a/rust/threshold-schnorr/src/schnorr_example_rust/build.sh b/rust/threshold-schnorr/src/schnorr_example_rust/build.sh new file mode 100755 index 000000000..b2baea24c --- /dev/null +++ b/rust/threshold-schnorr/src/schnorr_example_rust/build.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +set -euo pipefail + +TARGET="wasm32-unknown-unknown" +CANISTER="schnorr_example_rust" +SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" + +pushd $SCRIPT_DIR + +# NOTE: On macOS a specific version of llvm-ar and clang need to be set here. +# Otherwise the wasm compilation of rust-secp256k1 will fail. +if [ "$(uname)" == "Darwin" ]; then + LLVM_PATH=$(brew --prefix llvm) + # On macs we need to use the brew versions + AR="${LLVM_PATH}/bin/llvm-ar" CC="${LLVM_PATH}/bin/clang" cargo build --target $TARGET --release +else + cargo build --target $TARGET --release +fi + +popd + diff --git a/rust/threshold-schnorr/src/schnorr_example_rust/schnorr_example.did b/rust/threshold-schnorr/src/schnorr_example_rust/schnorr_example.did index 63681815c..b0f1e3695 100644 --- a/rust/threshold-schnorr/src/schnorr_example_rust/schnorr_example.did +++ b/rust/threshold-schnorr/src/schnorr_example_rust/schnorr_example.did @@ -1,7 +1,8 @@ type SchnorrAlgorithm = variant {bip340secp256k1; ed25519}; service : { + for_test_only_change_management_canister_id : (text) -> (variant { Ok: null; Err: text }); public_key : (SchnorrAlgorithm) -> (variant { Ok: record { public_key_hex: text; }; Err: text }); - sign : (text, SchnorrAlgorithm) -> (variant { Ok: record { signature_hex: text; }; Err: text }); - verify : (text, text, text, SchnorrAlgorithm) -> (variant { Ok: record { is_signature_valid: bool; }; Err: text }); + sign : (text, SchnorrAlgorithm, opt text) -> (variant { Ok: record { signature_hex: text; }; Err: text }); + verify : (text, text, text, opt text, SchnorrAlgorithm) -> (variant { Ok: record { is_signature_valid: bool; }; Err: text }); } diff --git a/rust/threshold-schnorr/src/schnorr_example_rust/src/all_architectures.rs b/rust/threshold-schnorr/src/schnorr_example_rust/src/all_architectures.rs index e03382754..65e0dd4b1 100644 --- a/rust/threshold-schnorr/src/schnorr_example_rust/src/all_architectures.rs +++ b/rust/threshold-schnorr/src/schnorr_example_rust/src/all_architectures.rs @@ -1,7 +1,7 @@ use candid::CandidType; use serde::{Deserialize, Serialize}; -#[derive(CandidType, Serialize, Deserialize, Debug, Copy, Clone)] +#[derive(CandidType, Serialize, Deserialize, Debug, Copy, Clone, PartialEq)] pub enum SchnorrAlgorithm { #[serde(rename = "bip340secp256k1")] Bip340Secp256k1, @@ -19,7 +19,7 @@ pub struct SignatureReply { pub signature_hex: String, } -#[derive(CandidType, Serialize, Deserialize, Debug)] +#[derive(CandidType, Serialize, Deserialize, Debug, PartialEq, Clone)] pub struct SignatureVerificationReply { pub is_signature_valid: bool, } diff --git a/rust/threshold-schnorr/src/schnorr_example_rust/src/wasm_only.rs b/rust/threshold-schnorr/src/schnorr_example_rust/src/wasm_only.rs index f9fef1fe7..3912db578 100644 --- a/rust/threshold-schnorr/src/schnorr_example_rust/src/wasm_only.rs +++ b/rust/threshold-schnorr/src/schnorr_example_rust/src/wasm_only.rs @@ -1,8 +1,14 @@ use super::{PublicKeyReply, SchnorrAlgorithm, SignatureReply, SignatureVerificationReply}; +use bitcoin::{ + key::{Secp256k1, TapTweak}, + XOnlyPublicKey, +}; use candid::{CandidType, Principal}; use ic_cdk::{query, update}; use serde::{Deserialize, Serialize}; -use std::convert::{TryFrom, TryInto}; +use serde_bytes::ByteBuf; +use std::cell::RefCell; +use std::convert::TryInto; type CanisterId = Principal; @@ -28,30 +34,56 @@ struct SchnorrKeyId { #[derive(CandidType, Serialize, Debug)] struct ManagementCanisterSignatureRequest { pub message: Vec, + pub aux: Option, pub derivation_path: Vec>, pub key_id: SchnorrKeyId, } +#[derive(Eq, PartialEq, Debug, CandidType, Serialize)] +pub enum SignWithSchnorrAux { + #[serde(rename = "bip341")] + Bip341(SignWithBip341Aux), +} + +#[derive(Eq, PartialEq, Debug, CandidType, Serialize)] +pub struct SignWithBip341Aux { + pub merkle_root_hash: ByteBuf, +} + #[derive(CandidType, Deserialize, Debug)] struct ManagementCanisterSignatureReply { pub signature: Vec, } +thread_local! { + static STATE: RefCell = RefCell::new("aaaaa-aa".to_string()); +} + +#[update] +async fn for_test_only_change_management_canister_id(id: String) -> Result<(), String> { + let _ = CanisterId::from_text(&id).map_err(|e| panic!("invalid canister id: {}: {}", id, e)); + STATE.with_borrow_mut(move |current_id| { + println!( + "Changing management canister id from {} to {id}", + *current_id + ); + *current_id = id; + }); + Ok(()) +} + #[update] async fn public_key(algorithm: SchnorrAlgorithm) -> Result { let request = ManagementCanisterSchnorrPublicKeyRequest { canister_id: None, derivation_path: vec![ic_cdk::api::caller().as_slice().to_vec()], - key_id: SchnorrKeyIds::TestKey1.to_key_id(algorithm), + key_id: SchnorrKeyIds::ChainkeyTestingCanisterKey1.to_key_id(algorithm), }; - let (res,): (ManagementCanisterSchnorrPublicKeyReply,) = ic_cdk::call( - Principal::management_canister(), - "schnorr_public_key", - (request,), - ) - .await - .map_err(|e| format!("schnorr_public_key failed {}", e.1))?; + let (res,): (ManagementCanisterSchnorrPublicKeyReply,) = + ic_cdk::call(mgmt_canister_id(), "schnorr_public_key", (request,)) + .await + .map_err(|e| format!("schnorr_public_key failed {}", e.1))?; Ok(PublicKeyReply { public_key_hex: hex::encode(&res.public_key), @@ -59,16 +91,40 @@ async fn public_key(algorithm: SchnorrAlgorithm) -> Result Result { +async fn sign( + message: String, + algorithm: SchnorrAlgorithm, + opt_merkle_tree_root_hex: Option, +) -> Result { + let aux = opt_merkle_tree_root_hex + .map(|hex| { + hex::decode(&hex) + .map_err(|e| format!("failed to decode hex: {e:?}")) + .and_then(|bytes| { + if bytes.len() == 32 || bytes.is_empty() { + Ok(SignWithSchnorrAux::Bip341(SignWithBip341Aux { + merkle_root_hash: ByteBuf::from(bytes), + })) + } else { + Err(format!( + "merkle tree root bytes must be 0 or 32 bytes long but got {}", + bytes.len() + )) + } + }) + }) + .transpose()?; + let internal_request = ManagementCanisterSignatureRequest { message: message.as_bytes().to_vec(), derivation_path: vec![ic_cdk::api::caller().as_slice().to_vec()], - key_id: SchnorrKeyIds::TestKey1.to_key_id(algorithm), + key_id: SchnorrKeyIds::ChainkeyTestingCanisterKey1.to_key_id(algorithm), + aux, }; let (internal_reply,): (ManagementCanisterSignatureReply,) = ic_cdk::api::call::call_with_payment( - Principal::management_canister(), + mgmt_canister_id(), "sign_with_schnorr", (internal_request,), 26_153_846_153, @@ -86,6 +142,7 @@ async fn verify( signature_hex: String, message: String, public_key_hex: String, + opt_merkle_tree_root_hex: Option, algorithm: SchnorrAlgorithm, ) -> Result { let sig_bytes = hex::decode(&signature_hex).expect("failed to hex-decode signature"); @@ -93,10 +150,20 @@ async fn verify( let pk_bytes = hex::decode(&public_key_hex).expect("failed to hex-decode public key"); match algorithm { - SchnorrAlgorithm::Bip340Secp256k1 => { - verify_bip340_secp256k1(&sig_bytes, msg_bytes, &pk_bytes) + SchnorrAlgorithm::Bip340Secp256k1 => match opt_merkle_tree_root_hex { + Some(merkle_tree_root_hex) => { + let merkle_tree_root_bytes = hex::decode(&merkle_tree_root_hex) + .expect("failed to hex-decode merkle tree root"); + verify_bip341_secp256k1(&sig_bytes, msg_bytes, &pk_bytes, &merkle_tree_root_bytes) + } + None => verify_bip340_secp256k1(&sig_bytes, msg_bytes, &pk_bytes), + }, + SchnorrAlgorithm::Ed25519 => { + if let Some(_) = opt_merkle_tree_root_hex { + return Err("ed25519 does not support merkle tree root verification".to_string()); + } + verify_ed25519(&sig_bytes, &msg_bytes, &pk_bytes) } - SchnorrAlgorithm::Ed25519 => verify_ed25519(&sig_bytes, &msg_bytes, &pk_bytes), } } @@ -107,13 +174,56 @@ fn verify_bip340_secp256k1( ) -> Result { assert_eq!(secp1_pk_bytes.len(), 33); - let sig = - k256::schnorr::Signature::try_from(sig_bytes).expect("failed to deserialize signature"); + let sig = bitcoin::secp256k1::schnorr::Signature::from_slice(sig_bytes) + .expect("failed to deserialize signature"); - let vk = k256::schnorr::VerifyingKey::from_bytes(&secp1_pk_bytes[1..]) + let pk = bitcoin::secp256k1::XOnlyPublicKey::from_slice(&secp1_pk_bytes[1..]) .expect("failed to deserialize BIP340 encoding into public key"); - let is_signature_valid = vk.verify_raw(&msg_bytes, &sig).is_ok(); + let secp256k1_engine = Secp256k1::new(); + let msg = + bitcoin::secp256k1::Message::from_digest_slice(msg_bytes).expect("failed to parse message"); + let is_signature_valid = pk.verify(&secp256k1_engine, &msg, &sig).is_ok(); + + Ok(SignatureVerificationReply { is_signature_valid }) +} + +fn verify_bip341_secp256k1( + sig_bytes: &[u8], + msg_bytes: &[u8], + secp1_pk_bytes: &[u8], + merkle_tree_root_bytes: &[u8], +) -> Result { + assert_eq!(secp1_pk_bytes.len(), 33); + + let pk = XOnlyPublicKey::from_slice(&secp1_pk_bytes[1..]).unwrap(); + let tweaked_pk_bytes = { + let secp256k1_engine = Secp256k1::new(); + let merkle_root = if merkle_tree_root_bytes.len() == 0 { + None + } else { + Some( + bitcoin::hashes::Hash::from_slice(&merkle_tree_root_bytes) + .expect("failed to create TapBranchHash"), + ) + }; + + pk.tap_tweak(&secp256k1_engine, merkle_root) + .0 + .to_inner() + .serialize() + }; + + let sig = bitcoin::secp256k1::schnorr::Signature::from_slice(sig_bytes) + .expect("failed to deserialize signature"); + + let pk = bitcoin::secp256k1::XOnlyPublicKey::from_slice(&tweaked_pk_bytes) + .expect("failed to deserialize tweaked BIP340 encoding into public key"); + + let secp256k1_engine = Secp256k1::new(); + let msg = + bitcoin::secp256k1::Message::from_digest_slice(msg_bytes).expect("failed to parse message"); + let is_signature_valid = pk.verify(&secp256k1_engine, &msg, &sig).is_ok(); Ok(SignatureVerificationReply { is_signature_valid }) } @@ -138,6 +248,8 @@ fn verify_ed25519( } enum SchnorrKeyIds { + #[allow(unused)] + ChainkeyTestingCanisterKey1, #[allow(unused)] TestKeyLocalDevelopment, #[allow(unused)] @@ -151,7 +263,8 @@ impl SchnorrKeyIds { SchnorrKeyId { algorithm, name: match self { - Self::TestKeyLocalDevelopment => "dfx_test_key", + Self::ChainkeyTestingCanisterKey1 => "insecure_test_key_1", + Self::TestKeyLocalDevelopment => "dfx_test_key_1", Self::TestKey1 => "test_key_1", Self::ProductionKey1 => "key_1", } @@ -160,6 +273,10 @@ impl SchnorrKeyIds { } } +fn mgmt_canister_id() -> CanisterId { + STATE.with_borrow(|state| CanisterId::from_text(&state).unwrap()) +} + // In the following, we register a custom getrandom implementation because // otherwise getrandom (which is a dependency of k256) fails to compile. // This is necessary because getrandom by default fails to compile for the diff --git a/rust/threshold-schnorr/src/schnorr_example_rust/tests/tests.rs b/rust/threshold-schnorr/src/schnorr_example_rust/tests/tests.rs index 1eb1b78cf..4929826ea 100644 --- a/rust/threshold-schnorr/src/schnorr_example_rust/tests/tests.rs +++ b/rust/threshold-schnorr/src/schnorr_example_rust/tests/tests.rs @@ -10,6 +10,8 @@ use std::path::Path; fn signing_and_verification_should_work_correctly() { const ALGORITHMS: [SchnorrAlgorithm; 2] = [SchnorrAlgorithm::Bip340Secp256k1, SchnorrAlgorithm::Ed25519]; + let merkle_root_hashes: [Option>; 4] = + [None, Some(vec![]), Some(vec![0; 8]), Some(vec![0; 32])]; let pic = PocketIcBuilder::new() .with_application_subnet() @@ -18,15 +20,38 @@ fn signing_and_verification_should_work_correctly() { .build(); for algorithm in ALGORITHMS { - for _trial in 0..5 { - test_impl(&pic, algorithm); + for merkle_root_hash in merkle_root_hashes.iter() { + for _trial in 0..5 { + test_impl(&pic, algorithm, merkle_root_hash.clone()); + } } } } -fn test_impl(pic: &PocketIc, algorithm: SchnorrAlgorithm) { +fn test_impl(pic: &PocketIc, algorithm: SchnorrAlgorithm, merkle_tree_root_bytes: Option>) { let my_principal = Principal::anonymous(); + // Create an empty canister as the anonymous principal and add cycles. + let schnorr_mock_canister_id = pic.create_canister(); + pic.add_cycles(schnorr_mock_canister_id, 2_000_000_000_000); + + let schnorr_mock_wasm_bytes = load_schnorr_mock_canister_wasm(); + pic.install_canister( + schnorr_mock_canister_id, + schnorr_mock_wasm_bytes, + vec![], + None, + ); + + let should_validate = (merkle_tree_root_bytes + .as_ref() + .map(|v| v.len() == 0 || v.len() == 32) + != Some(false) + && algorithm == SchnorrAlgorithm::Bip340Secp256k1) + || merkle_tree_root_bytes.is_none(); + + let merkle_tree_root_hex = merkle_tree_root_bytes.map(|v| hex::encode(v)); + // Create an empty example canister as the anonymous principal and add cycles. let example_canister_id = pic.create_canister(); pic.add_cycles(example_canister_id, 2_000_000_000_000); @@ -37,35 +62,75 @@ fn test_impl(pic: &PocketIc, algorithm: SchnorrAlgorithm) { // Make sure the canister is properly initialized fast_forward(&pic, 5); + let _dummy_reply: () = update( + &pic, + my_principal, + example_canister_id, + "for_test_only_change_management_canister_id", + encode_one(schnorr_mock_canister_id.to_text()).unwrap(), + ) + .expect("failed to update management canister id"); + // Make sure the example canister uses mock schnorr canister instead of + // the management canister + fast_forward(&pic, 5); + // a message we can reverse to break the signature - // currently pocket IC only supports 32B messages for BIP340 let message: String = std::iter::repeat('a') .take(16) .chain(std::iter::repeat('b').take(16)) .collect(); - let sig_reply: Result = update( + let pk_reply: Result = update( &pic, my_principal, example_canister_id, - "sign", - encode_args((message.clone(), algorithm)).unwrap(), + "public_key", + encode_one(algorithm).unwrap(), ); - let signature_hex = sig_reply.expect("failed to sign").signature_hex; + let public_key_hex = pk_reply.unwrap().public_key_hex; - let pk_reply: Result = update( + let successful_validation = Ok(SignatureVerificationReply { + is_signature_valid: true, + }); + + let sig_reply: Result = update( &pic, my_principal, example_canister_id, - "public_key", - encode_one(algorithm).unwrap(), + "sign", + encode_args((message.clone(), algorithm, merkle_tree_root_hex.clone())).unwrap(), ); - let public_key_hex = pk_reply.unwrap().public_key_hex; + if sig_reply.is_err() { + // If we failed to produce a signature with particular testing + // parameters, still test that the verification fails on dummy inputs. + assert!(!should_validate); + let dummy_signature_hex = String::from("a".repeat(64)); + assert_ne!( + update( + &pic, + my_principal, + example_canister_id, + "verify", + encode_args(( + dummy_signature_hex, + message.clone(), + public_key_hex.clone(), + merkle_tree_root_hex.clone(), + algorithm, + )) + .unwrap(), + ), + successful_validation.clone() + ); + return; + } + + let signature_hex = sig_reply.expect("failed to sign").signature_hex; { - let verification_reply: Result = update( + let verification_reply = update( &pic, my_principal, example_canister_id, @@ -74,12 +139,17 @@ fn test_impl(pic: &PocketIc, algorithm: SchnorrAlgorithm) { signature_hex.clone(), message.clone(), public_key_hex.clone(), + merkle_tree_root_hex.clone(), algorithm, )) .unwrap(), ); - assert!(verification_reply.unwrap().is_signature_valid); + if should_validate { + assert_eq!(verification_reply, successful_validation.clone()); + } else { + assert_ne!(verification_reply, successful_validation.clone()); + } } { @@ -92,12 +162,13 @@ fn test_impl(pic: &PocketIc, algorithm: SchnorrAlgorithm) { clone_and_reverse_chars(&signature_hex), message.clone(), public_key_hex.clone(), + merkle_tree_root_hex.clone(), algorithm, )) .unwrap(), ); - assert!(!verification_reply.unwrap().is_signature_valid); + assert_ne!(verification_reply, successful_validation.clone()); } { @@ -110,12 +181,13 @@ fn test_impl(pic: &PocketIc, algorithm: SchnorrAlgorithm) { signature_hex.clone(), clone_and_reverse_chars(&message), public_key_hex.clone(), + merkle_tree_root_hex.clone(), algorithm, )) .unwrap(), ); - assert!(!verification_reply.unwrap().is_signature_valid); + assert_ne!(verification_reply, successful_validation.clone()); } { @@ -128,15 +200,13 @@ fn test_impl(pic: &PocketIc, algorithm: SchnorrAlgorithm) { signature_hex.clone(), message.clone(), clone_and_reverse_chars(&public_key_hex), + merkle_tree_root_hex.clone(), algorithm, )) .unwrap(), ); - assert!( - verification_reply.is_err() || !verification_reply.unwrap().is_signature_valid, - "either the public key should fail to deserialize or the verification should fail" - ); + assert_ne!(verification_reply, successful_validation.clone()); } { @@ -149,6 +219,7 @@ fn test_impl(pic: &PocketIc, algorithm: SchnorrAlgorithm) { signature_hex.clone(), message.clone(), public_key_hex.clone(), + merkle_tree_root_hex.clone(), other_algorithm(algorithm), )) .unwrap(), @@ -185,6 +256,15 @@ fn load_schnorr_example_canister_wasm() -> Vec { zipped_bytes } +fn load_schnorr_mock_canister_wasm() -> Vec { + let wasm_url = "https://github.com/dfinity/chainkey-testing-canister/releases/download/v0.1.0/chainkey_testing_canister.wasm.gz"; + reqwest::blocking::get(wasm_url) + .unwrap() + .bytes() + .unwrap() + .to_vec() +} + pub fn update Deserialize<'de>>( ic: &PocketIc, sender: Principal, From 648f33f938a49ea821811ae5bdea86be4fb3fbe3 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Fri, 3 Jan 2025 15:58:32 -0600 Subject: [PATCH 16/51] Update rust/threshold-ecdsa/README.md --- rust/threshold-ecdsa/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/threshold-ecdsa/README.md b/rust/threshold-ecdsa/README.md index 031be0e66..1011152fe 100644 --- a/rust/threshold-ecdsa/README.md +++ b/rust/threshold-ecdsa/README.md @@ -62,7 +62,7 @@ Deploying to the Internet Computer requires [cycles](https://internetcomputer.or ### Update source code with the right key ID -To deploy the sample code, the canister needs the right key ID for the right environment. Specifically, one needs to replace the value of the `key_id` in the `src/ecdsa_example_rust/main.mo` file of the sample code. Before deploying to the mainnet, one should modify the code to use the right name of the `key_id`. +To deploy the sample code, the canister needs the right key ID for the right environment. Specifically, one needs to replace the value of the `key_id` in the `src/ecdsa_example_rust/src/lib.rs` file of the sample code. Before deploying to the mainnet, one should modify the code to use the right name of the `key_id`. There are three options: From 1312a1f17752934dffd96c357a6918dbcc989625 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Fri, 3 Jan 2025 16:11:31 -0600 Subject: [PATCH 17/51] Apply suggestions from code review --- rust/threshold-ecdsa/README.md | 3 +-- rust/threshold-schnorr/README.md | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/rust/threshold-ecdsa/README.md b/rust/threshold-ecdsa/README.md index 1011152fe..49a96a9b3 100644 --- a/rust/threshold-ecdsa/README.md +++ b/rust/threshold-ecdsa/README.md @@ -71,14 +71,13 @@ There are three options: * `key_1`: a master **production** key ID that is used in mainnet. > [!WARNING] -> To deploy to IC mainnet, one needs to replace the value in `key_id` fields with the values `"dfx_test_key"` to instead have either `"test_key_1"` or `"key_1"` depending on the desired intent. +> To deploy to IC mainnet, one needs to replace the value in `key_id `fields with the values `EcdsaKeyIds::TestKeyLocalDevelopment.to_key_id()` (mapping to `dfx_test_key`) to instead have either `EcdsaKeyIds::TestKey1.to_key_id()` (mapping to `test_key_1`) or `EcdsaKeyIds::ProductionKey1.to_key_id()` (mapping to `key_1`) depending on the desired intent. ### Deploying To [deploy via mainnet](https://internetcomputer.org/docs/current/developer-docs/setup/deploy-mainnet.md), run the following commands: ```bash -npm install dfx deploy --network ic ``` If successful, you should see something like this: diff --git a/rust/threshold-schnorr/README.md b/rust/threshold-schnorr/README.md index 45ed865d6..87c52df99 100644 --- a/rust/threshold-schnorr/README.md +++ b/rust/threshold-schnorr/README.md @@ -47,14 +47,11 @@ make deploy To test (includes deploying): ```bash -npm install @noble/curves make test ``` #### What this does - `make deploy` deploys the canister code on the local version of the IC -- `npm install @noble/curves` installs a test javascript dependency -- `make test` deploys and tests the canister code on the local version of the IC If deployment was successful, you should see something like this: @@ -66,6 +63,7 @@ URLs: ``` If you open the URL in a web browser, you will see a web UI that shows the +`sign`, and `verify` methods, those are rendered in the web UI. public methods the canister exposes. Since the canister exposes `public_key` and `sign`, those are rendered in the web UI. @@ -90,11 +88,22 @@ There are three options that are planed to be supported: * `test_key_1`: a master **test** key ID that is used in mainnet. * `key_1`: a master **production** key ID that is used in mainnet. +For example, the default code in `src/schnorr_example_rust/src/lib.rs` derives +the key ID as follows and can be deployed locally: +`SchnorrKeyIds::TestKeyLocalDevelopment.to_key_id(algorithm)` + IMPORTANT: To deploy to IC mainnet, one needs to replace `"dfx_test_key"` with either "test_key_1"` or `"key_1"` depending on the desired intent. Both uses of key ID in `src/schnorr_example_rust/src/main.mo` must be consistent. + +IMPORTANT: To deploy to IC mainnet, one needs to replace +`SchnorrKeyIds::TestKeyLocalDevelopment` (which maps to the `"dfx_test_key"` key +id) with either `SchnorrKeyIds::TestKey1` (`"test_key_1"`) or +`SchnorrKeyIds::ProductionKey1` (`"key_1"`) depending on the desired intent. +Both uses of key ID in `src/schnorr_example_rust/src/lib.rs` must be consistent. + ### Deploying To [deploy via the mainnet](https://internetcomputer.org/docs/current/developer-docs/setup/deploy-mainnet.md), run the following commands: @@ -112,10 +121,10 @@ URLs: ``` The implementation of this canister in Rust is (`schnorr_example_rust`) is -deployed on mainnet. It has the URL +deployed on the mainnet. It has the URL https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=enb64-iaaaa-aaaap-ahnkq-cai and serves up the Candid web UI for this particular canister deployed on -mainnet. +the mainnet. ## Obtaining public keys From f36dddb23f9217328b012e63f14f96e421b34a42 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Fri, 3 Jan 2025 16:12:16 -0600 Subject: [PATCH 18/51] Update README.md --- rust/threshold-schnorr/README.md | 149 ++++++++++++++++++++----------- 1 file changed, 96 insertions(+), 53 deletions(-) diff --git a/rust/threshold-schnorr/README.md b/rust/threshold-schnorr/README.md index 87c52df99..4c1dbc0d3 100644 --- a/rust/threshold-schnorr/README.md +++ b/rust/threshold-schnorr/README.md @@ -47,11 +47,14 @@ make deploy To test (includes deploying): ```bash +npm install @noble/curves make test ``` #### What this does - `make deploy` deploys the canister code on the local version of the IC +- `npm install @noble/curves` installs a test javascript dependency +- `make test` deploys and tests the canister code on the local version of the IC If deployment was successful, you should see something like this: @@ -63,7 +66,6 @@ URLs: ``` If you open the URL in a web browser, you will see a web UI that shows the -`sign`, and `verify` methods, those are rendered in the web UI. public methods the canister exposes. Since the canister exposes `public_key` and `sign`, those are rendered in the web UI. @@ -88,22 +90,11 @@ There are three options that are planed to be supported: * `test_key_1`: a master **test** key ID that is used in mainnet. * `key_1`: a master **production** key ID that is used in mainnet. -For example, the default code in `src/schnorr_example_rust/src/lib.rs` derives -the key ID as follows and can be deployed locally: -`SchnorrKeyIds::TestKeyLocalDevelopment.to_key_id(algorithm)` - IMPORTANT: To deploy to IC mainnet, one needs to replace `"dfx_test_key"` with either "test_key_1"` or `"key_1"` depending on the desired intent. Both uses of key ID in `src/schnorr_example_rust/src/main.mo` must be consistent. - -IMPORTANT: To deploy to IC mainnet, one needs to replace -`SchnorrKeyIds::TestKeyLocalDevelopment` (which maps to the `"dfx_test_key"` key -id) with either `SchnorrKeyIds::TestKey1` (`"test_key_1"`) or -`SchnorrKeyIds::ProductionKey1` (`"key_1"`) depending on the desired intent. -Both uses of key ID in `src/schnorr_example_rust/src/lib.rs` must be consistent. - ### Deploying To [deploy via the mainnet](https://internetcomputer.org/docs/current/developer-docs/setup/deploy-mainnet.md), run the following commands: @@ -121,10 +112,10 @@ URLs: ``` The implementation of this canister in Rust is (`schnorr_example_rust`) is -deployed on the mainnet. It has the URL +deployed on mainnet. It has the URL https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=enb64-iaaaa-aaaap-ahnkq-cai and serves up the Candid web UI for this particular canister deployed on -the mainnet. +mainnet. ## Obtaining public keys @@ -145,6 +136,42 @@ Ed25519 public key. } ``` +### Code walkthrough + +Open the file `wasm_only.rs`, which will show the following Rust code that +demonstrates how to obtain a Schnorr public key. + +```rust +#[update] +async fn public_key(algorithm: SchnorrAlgorithm) -> Result { + let request = ManagementCanisterSchnorrPublicKeyRequest { + canister_id: None, + derivation_path: vec![ic_cdk::api::caller().as_slice().to_vec()], + key_id: SchnorrKeyIds::TestKeyLocalDevelopment.to_key_id(algorithm), + }; + + let (res,): (ManagementCanisterSchnorrPublicKeyReply,) = + ic_cdk::call(Principal::management_canister(), "schnorr_public_key", (request,)) + .await + .map_err(|e| format!("schnorr_public_key failed {}", e.1))?; + + Ok(PublicKeyReply { + public_key_hex: hex::encode(&res.public_key), + }) +} +``` +In the code above, the canister calls the `schnorr_public_key` method of the [IC management canister](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-management-canister) (`aaaaa-aa`). + + +**The [IC management +canister](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-management-canister) +is just a facade; it does not exist as a canister (with isolated state, Wasm +code, etc.). It is an ergonomic way for canisters to call the system API of the +IC (as if it were a single canister). In the code below, we use the management +canister to create a Schnorr public key. Canister ID `"aaaaa-aa"` +declares the IC management canister in the canister code.** + + ### Canister root public key For obtaining the canister's root public key, the derivation path in the API can be simply left empty. @@ -158,51 +185,67 @@ For obtaining the canister's root public key, the derivation path in the API can Computing threshold Schnorr signatures is the core functionality of this feature. **Canisters do not hold Schnorr keys themselves**, but keys are derived from a master key held by dedicated subnets. A canister can request the computation of a signature through the management canister API. The request is then routed to a subnet holding the specified key and the subnet computes the requested signature using threshold cryptography. Thereby, it derives the canister root key or a key obtained through further derivation, as part of the signature protocol, from a shared secret and the requesting canister's principal identifier. Thus, a canister can only request signatures to be created for its canister root key or a key derived from it. This means, that canisters "control" their private Schnorr keys in that they decide when signatures are to be created with them, but don't hold a private key themselves. -## Signature verification - -For completeness of the example, we show that the created signatures can be -verified with the public key corresponding to the same canister and derivation -path in javascript. Note that in contrast to the Rust implementation of this -example, the signature verification is not part of the canister API and happens -externally. - -Ed25519 can be verified as follows: -```javascript -import('@noble/curves/ed25519').then((ed25519) => { verify(ed25519.ed25519); }) - .catch((err) => { console.log(err) }); - -function verify(ed25519) { - const test_sig = '1efa03b7b7f9077449a0f4b3114513f9c90ccf214166a8907c23d9c2bbbd0e0e6e630f67a93c1bd525b626120e86846909aedf4c58763ae8794bcef57401a301' - const test_pubkey = '566d53caf990f5f096d151df70b2a75107fac6724cb61a9d6d2aa63e1496b003' - const test_msg = Uint8Array.from(Buffer.from("hello", 'utf8')); - - console.log(ed25519.verify(test_sig, test_msg, test_pubkey)); - } +```rust +#[update] +async fn sign(message: String, algorithm: SchnorrAlgorithm) -> Result { + let internal_request = ManagementCanisterSignatureRequest { + message: message.as_bytes().to_vec(), + derivation_path: vec![ic_cdk::api::caller().as_slice().to_vec()], + key_id: SchnorrKeyIds::TestKeyLocalDevelopment.to_key_id(algorithm), + }; + + let (internal_reply,): (ManagementCanisterSignatureReply,) = + ic_cdk::api::call::call_with_payment( + Principal::management_canister(), + "sign_with_schnorr", + (internal_request,), + 25_000_000_000, + ) + .await + .map_err(|e| format!("sign_with_schnorr failed {e:?}"))?; + + Ok(SignatureReply { + signature_hex: hex::encode(&internal_reply.signature), + }) +} ``` -BIP340 can be verified as follows: -```javascript -import('@noble/curves/secp256k1').then((bip340) => { verify(bip340.schnorr); }) - .catch((err) => { console.log(err) }); -function verify(bip340) { - const test_sig = '1b64ca7a7f02c76633954f320675267685b3b80560eb6a35cda20291ddefc709364e59585771c284e46264bfbb0620e23eb8fb274994f7a6f2fcbc8a9430e5d7'; - // the first byte of the BIP340 public key is truncated - const pubkey = '0341d7cf39688e10b5f11f168ad0a9e790bcb429d7d486eab07d2c824b85821470'.substring(2) - const test_msg = Uint8Array.from(Buffer.from("hello", 'utf8')); +## Signature verification - console.log(bip340.verify(test_sig, test_msg, test_pubkey)); +For completeness of the example, we show that the created signatures can be +verified with the public key corresponding to the same canister and derivation +path path. Note that the first byte of the BIP340 public key needs to be removed for +verification, which is done by the verification function below internally. + +```rust +#[query] +async fn verify( + signature_hex: String, + message: String, + public_key_hex: String, + algorithm: SchnorrAlgorithm, +) -> Result { + let sig_bytes = hex::decode(&signature_hex).expect("failed to hex-decode signature"); + let msg_bytes = message.as_bytes(); + let pk_bytes = hex::decode(&public_key_hex).expect("failed to hex-decode public key"); + + match algorithm { + SchnorrAlgorithm::Bip340Secp256k1 => { + verify_bip340_secp256k1(&sig_bytes, msg_bytes, &pk_bytes) + } + SchnorrAlgorithm::Ed25519 => verify_ed25519(&sig_bytes, &msg_bytes, &pk_bytes), + } } -``` - -The call to `verify` function should always return `true` for correct parameters -and `false` or error otherwise. -Similar verifications can be done in many other languages with the help of -cryptographic libraries that support the `bip340secp256k1` signing *with -arbitrary message length* as specified in -[BIP340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#user-content-Messages_of_Arbitrary_Size) -and `ed25519` signing. +fn verify_bip340_secp256k1( + sig_bytes: &[u8], + msg_bytes: &[u8], + secp1_pk_bytes: &[u8], +) -> Result { + assert_eq!(secp1_pk_bytes.len(), 33); + assert_eq!(sig_bytes.len(), 64); +``` ## Conclusion From 1cf098147a71fb36ca491f797e9319ee3b48cfec Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Fri, 3 Jan 2025 16:14:36 -0600 Subject: [PATCH 19/51] Update rust/x509/README.md --- rust/x509/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/rust/x509/README.md b/rust/x509/README.md index 4a6e64495..d6596204d 100644 --- a/rust/x509/README.md +++ b/rust/x509/README.md @@ -38,7 +38,6 @@ up to the deployment and trying out the code on the mainnet. - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install) v`0.23.0` or newer. - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -The minimum version of `dfx` thatrun this example locally is - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` ## Deploy and test the canister locally From 2863b0c8111f8d7e3042eb6a112e2cc255679577 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Fri, 3 Jan 2025 16:14:42 -0600 Subject: [PATCH 20/51] Update rust/x509/README.md --- rust/x509/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/x509/README.md b/rust/x509/README.md index d6596204d..80a35be82 100644 --- a/rust/x509/README.md +++ b/rust/x509/README.md @@ -71,7 +71,7 @@ web UI. ## Deploying the canister on the mainnet -To deploy this canister the mainnet, you must do two things: +Before deploying this canister to the mainnet, you must do the following: - Acquire cycles (equivalent of "gas" in other blockchains). This is necessary for all canisters. - Update the sample source code to have the right key ID. This is unique to this canister. From 6d9ebfff74bcc759939c21ed25f8263ecaf65adb Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Fri, 3 Jan 2025 16:14:48 -0600 Subject: [PATCH 21/51] Update rust/x509/README.md --- rust/x509/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/rust/x509/README.md b/rust/x509/README.md index 80a35be82..74526d329 100644 --- a/rust/x509/README.md +++ b/rust/x509/README.md @@ -38,7 +38,6 @@ up to the deployment and trying out the code on the mainnet. - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install) v`0.23.0` or newer. - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` ## Deploy and test the canister locally From b53118e326123f553fdf8c36f7406fac6bbd72fb Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Fri, 3 Jan 2025 16:18:18 -0600 Subject: [PATCH 22/51] Update README.md --- rust/x509/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rust/x509/README.md b/rust/x509/README.md index 74526d329..500429750 100644 --- a/rust/x509/README.md +++ b/rust/x509/README.md @@ -75,11 +75,11 @@ Before deploying this canister to the mainnet, you must do the following: - Acquire cycles (equivalent of "gas" in other blockchains). This is necessary for all canisters. - Update the sample source code to have the right key ID. This is unique to this canister. -- #### Step 1: Acquire cycles to deploy +#### Step 1: Acquire cycles to deploy Deploying to the Internet Computer requires [cycles](https://internetcomputer.org/docs/current/developer-docs/getting-started/tokens-and-cycles) (the equivalent of "gas" on other blockchains). -- #### Step 2: Update source code with the right key ID +#### Step 2: Update source code with the right key ID To deploy the sample code, the canister needs the right key name for the right environment. Specifically, one needs to initialize the canister with the key @@ -95,7 +95,7 @@ There are three options that are supported: Note that `dfx deploy` formats those name in `PascalCase` instead of `snake_case` due to the formatting of types in `rust`. -- #### Step 3: Deploy to the mainnet using the IC SDK +#### Step 3: Deploy to the mainnet using the IC SDK To [deploy via the mainnet](https://internetcomputer.org/docs/current/developer-docs/setup/deploy-mainnet.md), run the following commands: From dbba00a4388703a98e3efdee156e657c6d2778a2 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Fri, 3 Jan 2025 16:18:43 -0600 Subject: [PATCH 23/51] Update rust/threshold-schnorr/README.md --- rust/threshold-schnorr/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/threshold-schnorr/README.md b/rust/threshold-schnorr/README.md index af5af3756..5ec1f0764 100644 --- a/rust/threshold-schnorr/README.md +++ b/rust/threshold-schnorr/README.md @@ -129,7 +129,7 @@ URLs: schnorr_example_rust: https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=enb64-iaaaa-aaaap-ahnkq-cai ``` -The implementation of this canister in Rust is (`schnorr_example_rust`) is +The implementation of this canister in Rust (`schnorr_example_rust`) is deployed on mainnet. It has the URL https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=enb64-iaaaa-aaaap-ahnkq-cai and serves up the Candid web UI for this particular canister deployed on From 1e75bc5ee86fa76a53a0bc153fcdf21900a830ad Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Mon, 6 Jan 2025 08:17:12 -0600 Subject: [PATCH 24/51] Update motoko/cert-var/README.md Co-authored-by: Nathan Mc Grath --- motoko/cert-var/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/motoko/cert-var/README.md b/motoko/cert-var/README.md index b0d985766..f5c082449 100644 --- a/motoko/cert-var/README.md +++ b/motoko/cert-var/README.md @@ -239,7 +239,7 @@ npm start ``` -## Step 8: Visit the frontend, and interact with application +## Step 8: Visit the frontend, and interact with the application ```bash http://localhost:8080/ From 9d7bd8e75a3fdad047a24f352fe59b401e5aa907 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Mon, 6 Jan 2025 08:22:01 -0600 Subject: [PATCH 25/51] Update README.md --- motoko/encrypted-notes-dapp-vetkd/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/motoko/encrypted-notes-dapp-vetkd/README.md b/motoko/encrypted-notes-dapp-vetkd/README.md index c12c50ceb..d0e7550a4 100644 --- a/motoko/encrypted-notes-dapp-vetkd/README.md +++ b/motoko/encrypted-notes-dapp-vetkd/README.md @@ -14,8 +14,6 @@ Please also see the [README of the original encrypted-notes-dapp](../encrypted-n This example uses an **insecure** implementation of [the proposed vetKD system API](https://github.com/dfinity/interface-spec/pull/158) in a pre-compiled form via the [vetkd_system_api.wasm](./vetkd_system_api.wasm). **Do not use this in production or for sensitive data**! This example is solely provided **for demonstration purposes** to collect feedback on the mentioned vetKD system API. -## Manual local deployment - ## Prerequisites This example requires an installation of: From bd03e6953e1e8a8a8a5d1d856a505c3c204ea456 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Mon, 6 Jan 2025 08:32:03 -0600 Subject: [PATCH 26/51] Update README.md --- motoko/threshold-ecdsa/README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/motoko/threshold-ecdsa/README.md b/motoko/threshold-ecdsa/README.md index 724caf20e..31b53d4df 100644 --- a/motoko/threshold-ecdsa/README.md +++ b/motoko/threshold-ecdsa/README.md @@ -15,7 +15,9 @@ This tutorial gives a complete overview of the development, starting with downlo > [!TIP] > This walkthrough focuses on the version of the sample canister code written in [Motoko](https://internetcomputer.org/docs/current/developer-docs/backend/motoko/index.md) programming language, but no specific knowledge of Motoko is needed to follow along. There is also a [Rust](https://github.com/dfinity/examples/tree/master/rust/threshold-ecdsa) version available in the same repo and follows the same commands for deploying. -## Prerequisites +## Local development + +### Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install) v0.11.0 or newer. @@ -23,7 +25,7 @@ This example requires an installation of: Begin by opening a terminal window. -## Step 1: Setup the project environment +### Step 1: Setup the project environment Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: @@ -32,7 +34,7 @@ cd examples/motoko/threshold-ecdsa dfx start --background ``` -## Step 2: Deploy the canisters +### Step 2: Deploy the canisters ```bash dfx deploy From 8f2549924ea172a76b30476d7533d30b3f271b3f Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Mon, 6 Jan 2025 08:32:32 -0600 Subject: [PATCH 27/51] Update README.md --- motoko/threshold-schnorr/README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/motoko/threshold-schnorr/README.md b/motoko/threshold-schnorr/README.md index f7697451a..ed2c2a25e 100644 --- a/motoko/threshold-schnorr/README.md +++ b/motoko/threshold-schnorr/README.md @@ -20,7 +20,9 @@ Motoko programming language. There is also a [Rust](https://github.com/dfinity/examples/tree/master/rust/threshold-schnorr) version available in the same repo and follows the same commands for deploying. -## Prerequisites +## Local development + +### Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). @@ -28,7 +30,7 @@ This example requires an installation of: Begin by opening a terminal window. -## Step 1: Setup the project environment +### Step 1: Setup the project environment Navigate into the folder containing the project's files, start a local instance of the Internet Computer and with the commands: @@ -40,7 +42,7 @@ dfx start --background #### What this does - `dfx start --background` starts a local instance of the IC via the IC SDK -## Step 2: Deploy the canisters +### Step 2: Deploy the canisters ```bash make deploy From f787714bd6be6c14cd56c673b0d0248527f91252 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Mon, 6 Jan 2025 08:38:51 -0600 Subject: [PATCH 28/51] Update rust/threshold-schnorr/README.md --- rust/threshold-schnorr/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/rust/threshold-schnorr/README.md b/rust/threshold-schnorr/README.md index 5ec1f0764..8c82694f6 100644 --- a/rust/threshold-schnorr/README.md +++ b/rust/threshold-schnorr/README.md @@ -47,7 +47,6 @@ make deploy To test (includes deploying): ```bash -npm install @noble/curves make test ``` From ce16e1029d258fcff3efc0b3590536578cf25ff7 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Mon, 6 Jan 2025 08:39:18 -0600 Subject: [PATCH 29/51] Update rust/threshold-schnorr/README.md --- rust/threshold-schnorr/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/rust/threshold-schnorr/README.md b/rust/threshold-schnorr/README.md index 8c82694f6..670fbda0a 100644 --- a/rust/threshold-schnorr/README.md +++ b/rust/threshold-schnorr/README.md @@ -65,6 +65,7 @@ URLs: ``` If you open the URL in a web browser, you will see a web UI that shows the +`sign`, and `verify` methods, those are rendered in the web UI. public methods the canister exposes. Since the canister exposes `public_key` and `sign`, those are rendered in the web UI. From f100b30d359eb7284600837913a9eb349fd7f89d Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Mon, 6 Jan 2025 08:40:14 -0600 Subject: [PATCH 30/51] Update rust/threshold-schnorr/README.md --- rust/threshold-schnorr/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rust/threshold-schnorr/README.md b/rust/threshold-schnorr/README.md index 670fbda0a..63ae4d1ab 100644 --- a/rust/threshold-schnorr/README.md +++ b/rust/threshold-schnorr/README.md @@ -108,6 +108,10 @@ There are four options that are planed to be supported: * `test_key_1`: a master **test** key ID that is used in mainnet. * `key_1`: a master **production** key ID that is used in mainnet. +For example, the default code in `src/schnorr_example_rust/src/lib.rs` derives +the key ID as follows and can be deployed locally: +`SchnorrKeyIds::TestKeyLocalDevelopment.to_key_id(algorithm)` + IMPORTANT: To deploy to IC mainnet, one needs to replace `"dfx_test_key"` with either "test_key_1"` or `"key_1"` depending on the desired intent. Both uses of key ID in `src/schnorr_example_rust/src/main.mo` must be consistent. From 94330212c2d64d1702878183bd01879842ee05d3 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Mon, 6 Jan 2025 08:50:19 -0600 Subject: [PATCH 31/51] Update README.md --- motoko/threshold-schnorr/README.md | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/motoko/threshold-schnorr/README.md b/motoko/threshold-schnorr/README.md index ed2c2a25e..8233d9903 100644 --- a/motoko/threshold-schnorr/README.md +++ b/motoko/threshold-schnorr/README.md @@ -48,16 +48,8 @@ dfx start --background make deploy ``` -To test (includes deploying): -```bash -npm install @noble/curves -make test -``` - #### What this does - `make deploy` deploys the canister code on the local version of the IC -- `npm install @noble/curves` installs a test javascript dependency -- `make test` deploys and tests the canister code on the local version of the IC If deployment was successful, you should see something like this: @@ -69,8 +61,8 @@ URLs: ``` If you open the URL in a web browser, you will see a web UI that shows the -public methods the canister exposes. Since the canister exposes `public_key` and -`sign`, those are rendered in the web UI. +public methods the canister exposes. Since the canister exposes `public_key`, +`sign`, and `verify`, those are rendered in the web UI. ## Deploying the canister on the mainnet @@ -93,17 +85,17 @@ There are three options that are planed to be supported: * `test_key_1`: a master **test** key ID that is used in mainnet. * `key_1`: a master **production** key ID that is used in mainnet. -For example, the default code in `src/schnorr_example_motoko/src/lib.rs` -hard-codes the used of `dfx_test_key` and derives the key ID as follows and can -be deployed locally: -```motoko -key_id = { algorithm = algorithm_arg; name = "dfx_test_key" } +For example, the default code in `src/schnorr_example_rust/src/lib.rs` derives +the key ID as follows and can be deployed locally: +```rust +SchnorrKeyIds::TestKeyLocalDevelopment.to_key_id(algorithm) ``` -IMPORTANT: To deploy to IC mainnet, one needs to replace `"dfx_test_key"` with - either "test_key_1"` or `"key_1"` depending on the desired intent. Both uses of -key ID in `src/schnorr_example_motoko/src/main.mo` must be consistent. - +IMPORTANT: To deploy to the mainnet, one needs to replace +`SchnorrKeyIds::TestKeyLocalDevelopment` (which maps to the `"dfx_test_key"` key +id) with either `SchnorrKeyIds::TestKey1` (`"test_key_1"`) or +`SchnorrKeyIds::ProductionKey1` (`"key_1"`) depending on the desired intent. +Both uses of key ID in `src/schnorr_example_rust/src/lib.rs` must be consistent. ### Deploying From dc1097e961fe13dfc00fb1dfb5b071e922741804 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Mon, 6 Jan 2025 08:52:31 -0600 Subject: [PATCH 32/51] Update README.md --- motoko/threshold-schnorr/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/motoko/threshold-schnorr/README.md b/motoko/threshold-schnorr/README.md index 8233d9903..234038de6 100644 --- a/motoko/threshold-schnorr/README.md +++ b/motoko/threshold-schnorr/README.md @@ -40,7 +40,7 @@ dfx start --background ``` #### What this does -- `dfx start --background` starts a local instance of the IC via the IC SDK +- `dfx start --background` starts a local instance of the IC via the IC SDK. ### Step 2: Deploy the canisters @@ -49,7 +49,7 @@ make deploy ``` #### What this does -- `make deploy` deploys the canister code on the local version of the IC +- `make deploy` deploys the canister code on the local version of the IC. If deployment was successful, you should see something like this: From f506660070fbda7b190620d17d66481d6d8fcc59 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Mon, 6 Jan 2025 08:55:57 -0600 Subject: [PATCH 33/51] Update README.md --- rust/threshold-schnorr/README.md | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/rust/threshold-schnorr/README.md b/rust/threshold-schnorr/README.md index 63ae4d1ab..cf21423b1 100644 --- a/rust/threshold-schnorr/README.md +++ b/rust/threshold-schnorr/README.md @@ -51,9 +51,7 @@ make test ``` #### What this does -- `make deploy` deploys the canister code on the local version of the IC -- `npm install @noble/curves` installs a test javascript dependency -- `make test` deploys and tests the canister code on the local version of the IC +- `make deploy` deploys the canister code on the local version of the IC. If deployment was successful, you should see something like this: @@ -66,8 +64,6 @@ URLs: If you open the URL in a web browser, you will see a web UI that shows the `sign`, and `verify` methods, those are rendered in the web UI. -public methods the canister exposes. Since the canister exposes `public_key` and -`sign`, those are rendered in the web UI. ## Deploying the canister on the mainnet @@ -80,7 +76,7 @@ To deploy this canister the mainnet, one needs to do two things: Deploying to the Internet Computer requires [cycles](https://internetcomputer.org/docs/current/developer-docs/getting-started/tokens-and-cycles) (the equivalent of "gas" on other blockchains). -#### Update management canister ID reference for testing +### Update management canister ID reference for testing The latest version of `dfx`, `v0.24.3`, does not yet support `opt_merkle_tree_root_hex` that is not `None`. Therefore, for local tests, [the @@ -96,7 +92,7 @@ automatically with `make mock`, which will install the chain-key testing caniste and use it instead of the management canister. Note that `dfx` should be running to successfully run `make mock`. -#### Update source code with the right key ID +### Update source code with the right key ID To deploy the sample code, the canister needs the right key ID for the right environment. Specifically, one needs to replace the value of the `key_id` in the `src/schnorr_example_rust/src/lib.rs` file of the sample code. Before deploying to mainnet, one should modify the code to use the right name of the `key_id`. @@ -113,8 +109,8 @@ the key ID as follows and can be deployed locally: `SchnorrKeyIds::TestKeyLocalDevelopment.to_key_id(algorithm)` IMPORTANT: To deploy to IC mainnet, one needs to replace `"dfx_test_key"` with -either "test_key_1"` or `"key_1"` depending on the desired intent. Both uses of -key ID in `src/schnorr_example_rust/src/main.mo` must be consistent. +either `"test_key_1"` or `"key_1"` depending on the desired intent. Both uses of +key ID in `src/schnorr_example_rust/src/lib.rs` must be consistent. ### Deploying @@ -274,7 +270,7 @@ async fn sign( For completeness of the example, we show that the created signatures can be verified with the public key corresponding to the same canister and derivation -path path. Note that the first byte of the BIP340 public key needs to be removed for +path. Note that the first byte of the BIP340 public key needs to be removed for verification, which is done by the verification function below internally. ```rust From 549cbc3d6bf2c25081daf8255a666500bc7169eb Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Mon, 6 Jan 2025 08:57:19 -0600 Subject: [PATCH 34/51] Update README.md --- rust/threshold-schnorr/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/rust/threshold-schnorr/README.md b/rust/threshold-schnorr/README.md index cf21423b1..572ff8617 100644 --- a/rust/threshold-schnorr/README.md +++ b/rust/threshold-schnorr/README.md @@ -63,6 +63,7 @@ URLs: ``` If you open the URL in a web browser, you will see a web UI that shows the +public methods the canister exposes. Since the canister exposes `public_key`, `sign`, and `verify` methods, those are rendered in the web UI. ## Deploying the canister on the mainnet From 8797bedc459a4b2ec3d753d69856e8a0bef3983d Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Mon, 6 Jan 2025 08:59:36 -0600 Subject: [PATCH 35/51] Update README.md --- rust/threshold-schnorr/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/threshold-schnorr/README.md b/rust/threshold-schnorr/README.md index 572ff8617..eaed645a6 100644 --- a/rust/threshold-schnorr/README.md +++ b/rust/threshold-schnorr/README.md @@ -97,7 +97,7 @@ to successfully run `make mock`. To deploy the sample code, the canister needs the right key ID for the right environment. Specifically, one needs to replace the value of the `key_id` in the `src/schnorr_example_rust/src/lib.rs` file of the sample code. Before deploying to mainnet, one should modify the code to use the right name of the `key_id`. -There are four options that are planed to be supported: +There are four options that are supported: * `insecure_test_key_1`: the key ID supported by the `chainkey_testing_canister` ([link](https://github.com/dfinity/chainkey-testing-canister/)). From 18a2ced21815a230c7988d392c8ff9bd64c19a25 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Mon, 6 Jan 2025 09:03:22 -0600 Subject: [PATCH 36/51] Update README.md --- rust/threshold-schnorr/README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/rust/threshold-schnorr/README.md b/rust/threshold-schnorr/README.md index eaed645a6..7f1125316 100644 --- a/rust/threshold-schnorr/README.md +++ b/rust/threshold-schnorr/README.md @@ -287,6 +287,32 @@ async fn verify( let msg_bytes = message.as_bytes(); let pk_bytes = hex::decode(&public_key_hex).expect("failed to hex-decode public key"); + match algorithm { + SchnorrAlgorithm::Bip340Secp256k1 => match opt_merkle_tree_root_hex { + Some(merkle_tree_root_hex) => { + let merkle_tree_root_bytes = hex::decode(&merkle_tree_root_hex) + .expect("failed to hex-decode merkle tree root"); + verify_bip341_secp256k1(&sig_bytes, msg_bytes, &pk_bytes, &merkle_tree_root_bytes) + } + None => verify_bip340_secp256k1(&sig_bytes, msg_bytes, &pk_bytes), + }, + SchnorrAlgorithm::Ed25519 => { + if let Some(_) = opt_merkle_tree_root_hex { + return Err("ed25519 does not support merkle tree root verification".to_string()); + } + verify_ed25519(&sig_bytes, &msg_bytes, &pk_bytes) + } + } +} + +fn verify_bip340_secp256k1( + sig_bytes: &[u8], + msg_bytes: &[u8], + secp1_pk_bytes: &[u8], +) -> Result { + assert_eq!(secp1_pk_bytes.len(), 33); + assert_eq!(sig_bytes.len(), 64); + let sig = k256::schnorr::Signature::try_from(sig_bytes).expect("failed to deserialize signature"); From 9c6266807d7641b46d2f054c5e79f471c9fd8074 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Mon, 6 Jan 2025 09:07:07 -0600 Subject: [PATCH 37/51] Update README.md --- motoko/threshold-schnorr/README.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/motoko/threshold-schnorr/README.md b/motoko/threshold-schnorr/README.md index 234038de6..6c7603114 100644 --- a/motoko/threshold-schnorr/README.md +++ b/motoko/threshold-schnorr/README.md @@ -85,17 +85,18 @@ There are three options that are planed to be supported: * `test_key_1`: a master **test** key ID that is used in mainnet. * `key_1`: a master **production** key ID that is used in mainnet. -For example, the default code in `src/schnorr_example_rust/src/lib.rs` derives -the key ID as follows and can be deployed locally: -```rust -SchnorrKeyIds::TestKeyLocalDevelopment.to_key_id(algorithm) +For example, the default code in `src/schnorr_example_motoko/src/main.mo` +hard-codes the used of `dfx_test_key` and derives the key ID as follows and can +be deployed locally: + + +```motoko +key_id = { algorithm = algorithm_arg; name = "dfx_test_key" } ``` -IMPORTANT: To deploy to the mainnet, one needs to replace -`SchnorrKeyIds::TestKeyLocalDevelopment` (which maps to the `"dfx_test_key"` key -id) with either `SchnorrKeyIds::TestKey1` (`"test_key_1"`) or -`SchnorrKeyIds::ProductionKey1` (`"key_1"`) depending on the desired intent. -Both uses of key ID in `src/schnorr_example_rust/src/lib.rs` must be consistent. +IMPORTANT: To deploy to IC mainnet, one needs to replace `"dfx_test_key"` with +either `"test_key_1"` or `"key_1"` depending on the desired intent. Both uses of +key ID in `src/schnorr_example_motoko/src/main.mo` must be consistent. ### Deploying From 10261f700027a229518ada3a798add3f0f4ad50b Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Tue, 7 Jan 2025 08:55:56 -0600 Subject: [PATCH 38/51] Update README.md --- rust/threshold-ecdsa/README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/rust/threshold-ecdsa/README.md b/rust/threshold-ecdsa/README.md index 49a96a9b3..32531c2a6 100644 --- a/rust/threshold-ecdsa/README.md +++ b/rust/threshold-ecdsa/README.md @@ -15,7 +15,9 @@ This tutorial gives a complete overview of the development, starting with downlo > [!TIP] > This walkthrough focuses on the version of the sample canister code written in the Rust programming language. There is also a [Motoko](https://internetcomputer.org/docs/current/developer-docs/backend/motoko/index.md) version available in the same repo and follows the same commands for deploying. -## Prerequisites +## Local deployment + +### Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install) v0.11.0 or newer. @@ -23,7 +25,7 @@ This example requires an installation of: Begin by opening a terminal window. -## Step 1: Setup the project environment +### Step 1: Setup the project environment Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: @@ -32,7 +34,7 @@ cd examples/rust/threshold-ecdsa dfx start --background ``` -## Step 2: Deploy the canisters +### Step 2: Deploy the canisters ```bash dfx deploy @@ -147,4 +149,4 @@ In this walkthrough, we deployed a sample smart contract that: * Signed with private ECDSA keys even though **canisters do not hold ECDSA keys themselves**. * Requested a public key. -* Performed signature verification. \ No newline at end of file +* Performed signature verification. From 86fdba27fa7a70aad78e963658280db34fa5910b Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Tue, 7 Jan 2025 08:56:54 -0600 Subject: [PATCH 39/51] Update README.md --- rust/threshold-schnorr/README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rust/threshold-schnorr/README.md b/rust/threshold-schnorr/README.md index 7f1125316..60957756c 100644 --- a/rust/threshold-schnorr/README.md +++ b/rust/threshold-schnorr/README.md @@ -25,9 +25,11 @@ This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` +## Local deployment + Begin by opening a terminal window. -## Step 1: Setup the project environment +### Step 1: Setup the project environment Navigate into the folder containing the project's files, start a local instance of the Internet Computer and with the commands: @@ -39,7 +41,7 @@ dfx start --background #### What this does - `dfx start --background` starts a local instance of the IC via the IC SDK -## Step 2: Deploy the canisters +### Step 2: Deploy the canisters ```bash make deploy From 0a7e58f16bb94fe562f346af42bc23cd93813011 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Tue, 7 Jan 2025 08:57:29 -0600 Subject: [PATCH 40/51] Update README.md --- rust/threshold-ecdsa/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rust/threshold-ecdsa/README.md b/rust/threshold-ecdsa/README.md index 32531c2a6..fe531b0cf 100644 --- a/rust/threshold-ecdsa/README.md +++ b/rust/threshold-ecdsa/README.md @@ -15,14 +15,14 @@ This tutorial gives a complete overview of the development, starting with downlo > [!TIP] > This walkthrough focuses on the version of the sample canister code written in the Rust programming language. There is also a [Motoko](https://internetcomputer.org/docs/current/developer-docs/backend/motoko/index.md) version available in the same repo and follows the same commands for deploying. -## Local deployment - -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install) v0.11.0 or newer. - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` +## Local deployment + Begin by opening a terminal window. ### Step 1: Setup the project environment From dd3c0cb78c5408d4c94cce25f60f119e2aa14a7f Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Tue, 7 Jan 2025 16:11:14 -0600 Subject: [PATCH 41/51] Update rust/icp_transfer/README.md Co-authored-by: Marco Walz <8124114+marc0olo@users.noreply.github.com> --- rust/icp_transfer/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/icp_transfer/README.md b/rust/icp_transfer/README.md index 429d4fbee..c2fa459d2 100644 --- a/rust/icp_transfer/README.md +++ b/rust/icp_transfer/README.md @@ -269,7 +269,7 @@ TOKENS_TRANSFER_ACCOUNT_ID_BYTES="$(python3 -c 'print("vec{" + ";".join([str(b) ## Step 11: Transfer funds to your canister > [!TIP] -> Make sure that you are using the default `dfx` account that we minted tokens to in step 7 for the following steps. +> Make sure that you are using the default `dfx` account that we minted tokens to in step 6 for the following steps. Make the following call to transfer funds to the canister: From 5bc62dc07d2e212525e2de2b7058eeefbf1d458f Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Tue, 7 Jan 2025 16:11:26 -0600 Subject: [PATCH 42/51] Update rust/pub-sub/README.md Co-authored-by: Marco Walz <8124114+marc0olo@users.noreply.github.com> --- rust/pub-sub/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/pub-sub/README.md b/rust/pub-sub/README.md index fe483135f..a97f5a1e4 100644 --- a/rust/pub-sub/README.md +++ b/rust/pub-sub/README.md @@ -30,7 +30,7 @@ dfx canister id publisher ## Step 3: Subscribe to the "Apples" topic ```bash -dfx canister call subscriber setup_subscribe '(principal "", "Apples")' +dfx canister call subscriber setup_subscribe '(principal "", "Apples")' ``` ## Step 4: Publish to the "Apples" topic From d96f4ba1c7127cb39d190993d8897ed848d5cfcc Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Tue, 7 Jan 2025 16:12:59 -0600 Subject: [PATCH 43/51] Update motoko/token_transfer_from/README.md Co-authored-by: Marco Walz <8124114+marc0olo@users.noreply.github.com> --- motoko/token_transfer_from/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/motoko/token_transfer_from/README.md b/motoko/token_transfer_from/README.md index 1f455b918..860c6581c 100644 --- a/motoko/token_transfer_from/README.md +++ b/motoko/token_transfer_from/README.md @@ -242,7 +242,7 @@ dfx deploy token_transfer_from_backend :::info -Make sure that you are using the default `dfx` account that we minted tokens to in step 5 for the following steps. +Make sure that you are using the default `dfx` account that we minted tokens to in step 6 for the following steps. ::: From fc6d4b1883cde7f03b55aa7e6d1a86811e627ead Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Tue, 7 Jan 2025 16:13:10 -0600 Subject: [PATCH 44/51] Update motoko/token_transfer/README.md Co-authored-by: Marco Walz <8124114+marc0olo@users.noreply.github.com> --- motoko/token_transfer/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/motoko/token_transfer/README.md b/motoko/token_transfer/README.md index 87076dadc..f24c83c25 100644 --- a/motoko/token_transfer/README.md +++ b/motoko/token_transfer/README.md @@ -222,7 +222,7 @@ dfx deploy token_transfer_backend ## Step 10: Transfer funds to your canister > [!TIP] -> Make sure that you are using the default `dfx` account that we minted tokens to in step 7 for the following steps. +> Make sure that you are using the default `dfx` account that we minted tokens to in step 6 for the following steps. Make the following call to transfer 10 tokens to the canister: From c0ff17ea119c208db4665b5134a835840382fc21 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Tue, 7 Jan 2025 16:15:13 -0600 Subject: [PATCH 45/51] Update README.md --- motoko/token_transfer_from/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/motoko/token_transfer_from/README.md b/motoko/token_transfer_from/README.md index 860c6581c..626b1a30d 100644 --- a/motoko/token_transfer_from/README.md +++ b/motoko/token_transfer_from/README.md @@ -52,8 +52,8 @@ Replace its contents with this but adapt the URLs to be the ones you determined ```json { "canisters": { - "token_transfer_backend": { - "main": "src/token_transfer_backend/main.mo", + "token_transfer_from_backend": { + "main": "src/token_transfer_from_backend/main.mo", "type": "motoko", "dependencies": ["icrc1_ledger_canister"] }, From 0b1e56d43d5e2ceebbe44059cc66fcc611a2c216 Mon Sep 17 00:00:00 2001 From: Kristofer Date: Wed, 8 Jan 2025 12:08:55 +0100 Subject: [PATCH 46/51] Set fixed versions of @dfinity packages --- rust/defi/src/frontend/package-lock.json | 10 +++++----- rust/defi/src/frontend/package.json | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/rust/defi/src/frontend/package-lock.json b/rust/defi/src/frontend/package-lock.json index 1a059f694..468e8f34a 100644 --- a/rust/defi/src/frontend/package-lock.json +++ b/rust/defi/src/frontend/package-lock.json @@ -8,11 +8,11 @@ "name": "svelte-app", "version": "1.0.0", "dependencies": { - "@dfinity/agent": "^0.10.4", - "@dfinity/auth-client": "^0.10.4", - "@dfinity/authentication": "^0.10.4", - "@dfinity/candid": "^0.10.4", - "@dfinity/identity": "^0.10.4", + "@dfinity/agent": "0.10.4", + "@dfinity/auth-client": "0.10.4", + "@dfinity/authentication": "0.10.4", + "@dfinity/candid": "0.10.4", + "@dfinity/identity": "0.10.4", "@dfinity/principal": "0.10.4", "@fortawesome/fontawesome-svg-core": "^1.2.36", "@fortawesome/free-solid-svg-icons": "^5.15.4", diff --git a/rust/defi/src/frontend/package.json b/rust/defi/src/frontend/package.json index b877b04d8..59e92579d 100644 --- a/rust/defi/src/frontend/package.json +++ b/rust/defi/src/frontend/package.json @@ -22,11 +22,11 @@ "svelte": "^3.49.0" }, "dependencies": { - "@dfinity/agent": "^0.10.4", - "@dfinity/auth-client": "^0.10.4", - "@dfinity/authentication": "^0.10.4", - "@dfinity/candid": "^0.10.4", - "@dfinity/identity": "^0.10.4", + "@dfinity/agent": "0.10.4", + "@dfinity/auth-client": "0.10.4", + "@dfinity/authentication": "0.10.4", + "@dfinity/candid": "0.10.4", + "@dfinity/identity": "0.10.4", "@dfinity/principal": "0.10.4", "@fortawesome/fontawesome-svg-core": "^1.2.36", "@fortawesome/free-solid-svg-icons": "^5.15.4", From d18112948c5b9a20a105cbd825a33abac9f10dec Mon Sep 17 00:00:00 2001 From: Kristofer Date: Wed, 8 Jan 2025 13:10:34 +0100 Subject: [PATCH 47/51] DIP20, correct commit --- rust/defi/src/DIP20 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/defi/src/DIP20 b/rust/defi/src/DIP20 index 3083510b7..cd365711e 160000 --- a/rust/defi/src/DIP20 +++ b/rust/defi/src/DIP20 @@ -1 +1 @@ -Subproject commit 3083510b79825c3d3b2ee3087c40be23ca71176c +Subproject commit cd365711ee4f34af9a6e74ca77d6637ee29d1755 From dc992378fae024007dbc45e2c4b9813c27d3add7 Mon Sep 17 00:00:00 2001 From: Kristofer Date: Wed, 8 Jan 2025 14:31:02 +0100 Subject: [PATCH 48/51] Upgrade to Node 22 --- .github/workflows/provision-linux.sh | 32 ++++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/provision-linux.sh b/.github/workflows/provision-linux.sh index 5cd8ca63d..95d3c2b46 100755 --- a/.github/workflows/provision-linux.sh +++ b/.github/workflows/provision-linux.sh @@ -6,8 +6,8 @@ set -ex pushd /tmp # Install Node. -wget --output-document install-node.sh "https://deb.nodesource.com/setup_14.x" -sudo bash install-node.sh +wget --output-document nodesource_setup.sh "https://deb.nodesource.com/setup_lts.x" +sudo bash nodesource_setup.sh sudo apt-get install --yes nodejs rm install-node.sh @@ -15,20 +15,20 @@ rm install-node.sh wget --output-document install-dfx.sh "https://raw.githubusercontent.com/dfinity/sdk/master/public/install-dfxvm.sh" DFX_VERSION=${DFX_VERSION:=0.24.3} DFXVM_INIT_YES=true bash install-dfx.sh rm install-dfx.sh -echo "$HOME/.local/share/dfx/bin" >> $GITHUB_PATH +echo "$HOME/.local/share/dfx/bin" >>$GITHUB_PATH source "$HOME/.local/share/dfx/env" dfx cache install # check the current ic-commit found in the main branch, check if it differs from the one in this PR branch # if so, update the dfx cache with the latest ic artifacts if [ -f "${GITHUB_WORKSPACE}/.ic-commit" ]; then - stable_sha=$(curl https://raw.githubusercontent.com/dfinity/examples/master/.ic-commit) - current_sha=$(sed <"$GITHUB_WORKSPACE/.ic-commit" 's/#.*$//' | sed '/^$/d') - arch="x86_64-linux" - if [ "$current_sha" != "$stable_sha" ]; then - export current_sha - export arch - sh "$GITHUB_WORKSPACE/.github/workflows/update-dfx-cache.sh" - fi + stable_sha=$(curl https://raw.githubusercontent.com/dfinity/examples/master/.ic-commit) + current_sha=$(sed <"$GITHUB_WORKSPACE/.ic-commit" 's/#.*$//' | sed '/^$/d') + arch="x86_64-linux" + if [ "$current_sha" != "$stable_sha" ]; then + export current_sha + export arch + sh "$GITHUB_WORKSPACE/.github/workflows/update-dfx-cache.sh" + fi fi # Install ic-repl @@ -47,14 +47,14 @@ rustup target add wasm32-unknown-unknown # Install matchers matchers_version=1.2.0 -curl -fsSLO "https://github.com/kritzcreek/motoko-matchers/archive/refs/tags/v${matchers_version}.tar.gz" +curl -fsSLO "https://github.com/kritzcreek/motoko-matchers/archive/refs/tags/v${matchers_version}.tar.gz" tar -xzf "v${matchers_version}.tar.gz" --directory "$(dfx cache show)" rm "v${matchers_version}.tar.gz" mv "$(dfx cache show)/motoko-matchers-${matchers_version}" "$(dfx cache show)/motoko-matchers" # Install wasmtime wasmtime_version=0.33.1 -curl -fsSLO "https://github.com/bytecodealliance/wasmtime/releases/download/v${wasmtime_version}/wasmtime-v${wasmtime_version}-x86_64-linux.tar.xz" +curl -fsSLO "https://github.com/bytecodealliance/wasmtime/releases/download/v${wasmtime_version}/wasmtime-v${wasmtime_version}-x86_64-linux.tar.xz" mkdir -p "${HOME}/bin" tar -xf "wasmtime-v${wasmtime_version}-x86_64-linux.tar.xz" --directory "${HOME}/bin/" mv "${HOME}/bin/wasmtime-v${wasmtime_version}-x86_64-linux/wasmtime" "${HOME}/bin/wasmtime" @@ -66,13 +66,13 @@ cargo install --path wasi2ic --root "${HOME}" # Install wasm-opt version=117 -curl -fsSLO "https://github.com/WebAssembly/binaryen/releases/download/version_117/binaryen-version_${version}-x86_64-linux.tar.gz" +curl -fsSLO "https://github.com/WebAssembly/binaryen/releases/download/version_117/binaryen-version_${version}-x86_64-linux.tar.gz" tar -xzf "binaryen-version_${version}-x86_64-linux.tar.gz" --directory "${HOME}/" --strip-components 1 rm "binaryen-version_${version}-x86_64-linux.tar.gz" # Set environment variables. -echo "$HOME/bin" >> $GITHUB_PATH -echo "$HOME/.cargo/bin" >> $GITHUB_PATH +echo "$HOME/bin" >>$GITHUB_PATH +echo "$HOME/.cargo/bin" >>$GITHUB_PATH # Exit temporary directory. popd From dd84a5b76183ef7bdbe588aec234c70ea1c000b4 Mon Sep 17 00:00:00 2001 From: Kristofer Date: Wed, 8 Jan 2025 14:35:26 +0100 Subject: [PATCH 49/51] Cleanup --- .github/workflows/provision-linux.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/provision-linux.sh b/.github/workflows/provision-linux.sh index 95d3c2b46..38e6a5e24 100755 --- a/.github/workflows/provision-linux.sh +++ b/.github/workflows/provision-linux.sh @@ -9,7 +9,7 @@ pushd /tmp wget --output-document nodesource_setup.sh "https://deb.nodesource.com/setup_lts.x" sudo bash nodesource_setup.sh sudo apt-get install --yes nodejs -rm install-node.sh +rm nodesource_setup.sh # Install DFINITY SDK. wget --output-document install-dfx.sh "https://raw.githubusercontent.com/dfinity/sdk/master/public/install-dfxvm.sh" From a5c540252e60451756fa9638b5c4b7ac87e1605a Mon Sep 17 00:00:00 2001 From: Kristofer Date: Wed, 8 Jan 2025 22:44:51 +0100 Subject: [PATCH 50/51] Update @definity/x dependencies --- .../package-lock.json | 360 ++++-------------- .../package.json | 10 +- 2 files changed, 69 insertions(+), 301 deletions(-) diff --git a/motoko/internet_identity_integration/package-lock.json b/motoko/internet_identity_integration/package-lock.json index 76a76d1b3..0398f493c 100644 --- a/motoko/internet_identity_integration/package-lock.json +++ b/motoko/internet_identity_integration/package-lock.json @@ -8,11 +8,11 @@ "name": "internet_identity_integration", "version": "0.1.0", "devDependencies": { - "@dfinity/agent": "0.15.3", - "@dfinity/auth-client": "^0.15.3", - "@dfinity/candid": "0.15.3", - "@dfinity/identity": "^0.15.3", - "@dfinity/principal": "0.15.3", + "@dfinity/agent": "^2.2.0", + "@dfinity/auth-client": "^2.2.0", + "@dfinity/candid": "^2.2.0", + "@dfinity/identity": "^2.2.0", + "@dfinity/principal": "^2.2.0", "assert": "2.0.0", "buffer": "6.0.3", "copy-webpack-plugin": "^11.0.0", @@ -30,93 +30,69 @@ "node": "^12 || ^14 || ^16 || ^18" } }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, "node_modules/@dfinity/agent": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/@dfinity/agent/-/agent-0.15.3.tgz", - "integrity": "sha512-yjJnAWI2CQY9kAFgavXU4TiKjb3NwaKUpu2LwCfgtJM4k6ofKlW+7q0tBJNs5WvHqRcKRDdn4d6yXKQi+ubS+w==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@dfinity/agent/-/agent-2.2.0.tgz", + "integrity": "sha512-B0qpHf5vfnVNG3JZARC3Q9Cs2zG51/3LuTpCF4uVZ+4AgeRYHl4Erk/jmczdHNbSLIz1pe+F9seAYICovAnRIQ==", "dev": true, "dependencies": { + "@noble/curves": "^1.4.0", + "@noble/hashes": "^1.3.1", "base64-arraybuffer": "^0.2.0", - "bignumber.js": "^9.0.0", "borc": "^2.1.1", - "js-sha256": "0.9.0", - "simple-cbor": "^0.4.1", - "ts-node": "^10.8.2" + "buffer": "^6.0.3", + "simple-cbor": "^0.4.1" }, "peerDependencies": { - "@dfinity/candid": "^0.15.3", - "@dfinity/principal": "^0.15.3" + "@dfinity/candid": "^2.2.0", + "@dfinity/principal": "^2.2.0" } }, "node_modules/@dfinity/auth-client": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/@dfinity/auth-client/-/auth-client-0.15.3.tgz", - "integrity": "sha512-yM+0v1zKvPWVbOR1akvDcEMfHIvCSa7dII6jXrD/EW+VEcH7LhcWJIUIqz4vQw/QXXTB/CNKa6k7jvjr1XdXbw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@dfinity/auth-client/-/auth-client-2.2.0.tgz", + "integrity": "sha512-r3bIW2wLggCd5EO7H3JvE/xxBxPErndA1vpQN5bJi9V0VhqM9eMnjoPCm+cwaV8jZ4PCUFjYCxhSY40CfJZSfQ==", "dev": true, "dependencies": { "idb": "^7.0.2" }, "peerDependencies": { - "@dfinity/agent": "^0.15.3", - "@dfinity/identity": "^0.15.3", - "@dfinity/principal": "^0.15.3" + "@dfinity/agent": "^2.2.0", + "@dfinity/identity": "^2.2.0", + "@dfinity/principal": "^2.2.0" } }, "node_modules/@dfinity/candid": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/@dfinity/candid/-/candid-0.15.3.tgz", - "integrity": "sha512-jbfA+kr+gCrBuwxWm/j4Vpqzbnh9bsyUWu9CjopJis8xdxH3FIfNDWOzHZ/QaW7Co+6UoON1wzxMiy91/W5DQA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@dfinity/candid/-/candid-2.2.0.tgz", + "integrity": "sha512-6r21ow4kI/JaS6PocMVSHP49UDRG32EHrmFK9Uvg11yXulyTiR+PLGjabajvJjwmPQhjXiF8VzBIFY7aHOHiqQ==", "dev": true, - "dependencies": { - "ts-node": "^10.8.2" + "peerDependencies": { + "@dfinity/principal": "^2.2.0" } }, "node_modules/@dfinity/identity": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/@dfinity/identity/-/identity-0.15.3.tgz", - "integrity": "sha512-D5Sf01MvO3CO63nAYSdG2V8Ox4AEVAm+/O7oKU1oyg8m3z/9zklG6IyCOOKb6hQibWh81j+mduYuX4vYuEjSGw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@dfinity/identity/-/identity-2.2.0.tgz", + "integrity": "sha512-4L/i6pDYrGnpgnITHJR1Tb5umawqytZ8BhCE7G1MzG2ftWJ0SO1QJxRDwp5Nuj/fNZumq+ILSc3o3ItzaUs1iQ==", "dev": true, "dependencies": { - "borc": "^2.1.1", - "js-sha256": "^0.9.0", - "tweetnacl": "^1.0.1" + "@noble/curves": "^1.2.0", + "@noble/hashes": "^1.3.1", + "borc": "^2.1.1" }, "peerDependencies": { - "@dfinity/agent": "^0.15.3", - "@dfinity/principal": "^0.15.3", - "@peculiar/webcrypto": "^1.4.0" + "@dfinity/agent": "^2.2.0", + "@dfinity/principal": "^2.2.0" } }, "node_modules/@dfinity/principal": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/@dfinity/principal/-/principal-0.15.3.tgz", - "integrity": "sha512-XqHZVaJx/acmg6kFkF7PB156UwAquOS2WiAA753+nGKTG+TOC7OxbBXCr8vfEsd0mEzcmcLl+jLF8iUsC6Hk4w==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@dfinity/principal/-/principal-2.2.0.tgz", + "integrity": "sha512-8Yxb/6B4BWvV64HJ7X8sbDjoBaEamAQgOZ0MK0I44lZiRHomAYeUJMrw3yBg9jI1T62lijLcl401FAXBOzciiQ==", "dev": true, "dependencies": { - "js-sha256": "^0.9.0", - "ts-node": "^10.8.2" + "@noble/hashes": "^1.3.1" } }, "node_modules/@discoveryjs/json-ext": { @@ -192,6 +168,33 @@ "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", "dev": true }, + "node_modules/@noble/curves": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.0.tgz", + "integrity": "sha512-j84kjAbzEnQHaSIhRPUmB3/eVXu2k3dKPl2LOrR8fSOIL+89U+7lV117EWHtq/GHM3ReGHM46iRBdZfpc4HRUQ==", + "dev": true, + "dependencies": { + "@noble/hashes": "1.7.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.0.tgz", + "integrity": "sha512-HXydb0DgzTpDPwbVeDGCG1gIu7X6+AuU6Zl6av/E/KG8LMsvPntvq+w17CHRpKBmN6Ybdrt1eP3k4cj8DJa78w==", + "dev": true, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -227,72 +230,6 @@ "node": ">= 8" } }, - "node_modules/@peculiar/asn1-schema": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.3.3.tgz", - "integrity": "sha512-6GptMYDMyWBHTUKndHaDsRZUO/XMSgIns2krxcm2L7SEExRHwawFvSwNBhqNPR9HJwv3MruAiF1bhN0we6j6GQ==", - "dev": true, - "peer": true, - "dependencies": { - "asn1js": "^3.0.5", - "pvtsutils": "^1.3.2", - "tslib": "^2.4.0" - } - }, - "node_modules/@peculiar/json-schema": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/@peculiar/json-schema/-/json-schema-1.1.12.tgz", - "integrity": "sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==", - "dev": true, - "peer": true, - "dependencies": { - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@peculiar/webcrypto": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@peculiar/webcrypto/-/webcrypto-1.4.1.tgz", - "integrity": "sha512-eK4C6WTNYxoI7JOabMoZICiyqRRtJB220bh0Mbj5RwRycleZf9BPyZoxsTvpP0FpmVS2aS13NKOuh5/tN3sIRw==", - "dev": true, - "peer": true, - "dependencies": { - "@peculiar/asn1-schema": "^2.3.0", - "@peculiar/json-schema": "^1.1.12", - "pvtsutils": "^1.3.2", - "tslib": "^2.4.1", - "webcrypto-core": "^1.7.4" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true - }, "node_modules/@types/body-parser": { "version": "1.19.2", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", @@ -696,15 +633,6 @@ "acorn": "^8" } }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/ajv": { "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", @@ -784,33 +712,12 @@ "node": ">= 8" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, "node_modules/array-flatten": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", "dev": true }, - "node_modules/asn1js": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.5.tgz", - "integrity": "sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==", - "dev": true, - "peer": true, - "dependencies": { - "pvtsutils": "^1.3.2", - "pvutils": "^1.1.3", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/assert": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", @@ -1324,12 +1231,6 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1466,15 +1367,6 @@ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "dev": true }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -2754,12 +2646,6 @@ "node": ">= 10.13.0" } }, - "node_modules/js-sha256": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", - "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==", - "dev": true - }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -2826,12 +2712,6 @@ "tslib": "^2.0.3" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -3362,26 +3242,6 @@ "node": ">=6" } }, - "node_modules/pvtsutils": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.2.tgz", - "integrity": "sha512-+Ipe2iNUyrZz+8K/2IOo+kKikdtfhRKzNpQbruF2URmqPtoqAs8g3xS7TJvFF2GcPXjh7DkqMnpVveRFq4PgEQ==", - "dev": true, - "peer": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/pvutils": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.3.tgz", - "integrity": "sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -4226,61 +4086,12 @@ "node": ">=0.6" } }, - "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, "node_modules/tslib": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", "dev": true }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", - "dev": true - }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -4294,20 +4105,6 @@ "node": ">= 0.6" } }, - "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true, - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -4396,12 +4193,6 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -4433,20 +4224,6 @@ "minimalistic-assert": "^1.0.0" } }, - "node_modules/webcrypto-core": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.7.5.tgz", - "integrity": "sha512-gaExY2/3EHQlRNNNVSrbG2Cg94Rutl7fAaKILS1w8ZDhGxdFOaw6EbCfHIxPy9vt/xwp5o0VQAx9aySPF6hU1A==", - "dev": true, - "peer": true, - "dependencies": { - "@peculiar/asn1-schema": "^2.1.6", - "@peculiar/json-schema": "^1.1.12", - "asn1js": "^3.0.1", - "pvtsutils": "^1.3.2", - "tslib": "^2.4.0" - } - }, "node_modules/webpack": { "version": "5.76.0", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.0.tgz", @@ -4789,15 +4566,6 @@ "optional": true } } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } } } } diff --git a/motoko/internet_identity_integration/package.json b/motoko/internet_identity_integration/package.json index fa678e7dc..e94ed8a31 100644 --- a/motoko/internet_identity_integration/package.json +++ b/motoko/internet_identity_integration/package.json @@ -16,11 +16,11 @@ "generate": "dfx generate greet_backend" }, "devDependencies": { - "@dfinity/agent": "2.1.3", - "@dfinity/auth-client": "^2.1.3", - "@dfinity/candid": "2.1.3", - "@dfinity/identity": "^2.1.3", - "@dfinity/principal": "2.1.3", + "@dfinity/agent": "^2.2.0", + "@dfinity/auth-client": "^2.2.0", + "@dfinity/candid": "^2.2.0", + "@dfinity/identity": "^2.2.0", + "@dfinity/principal": "^2.2.0", "assert": "2.0.0", "buffer": "6.0.3", "copy-webpack-plugin": "^11.0.0", From 10b3ebaebbbb5789e4053878b6598640072509bf Mon Sep 17 00:00:00 2001 From: Marco Walz Date: Thu, 9 Jan 2025 08:36:19 +0100 Subject: [PATCH 51/51] update codeowner of iii example --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 256dadc60..59655d036 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -21,7 +21,7 @@ /motoko/hello_cycles/ @dfinity/languages /motoko/ic-pos/ @dfinity/growth /motoko/icrc2-swap/ @dfinity/growth -/motoko/internet_identity_integration/ @dfinity/gix +/motoko/internet_identity_integration/ @dfinity/identity /motoko/life/ @dfinity/languages /motoko/minimal-counter-dapp/ @dfinity/growth /motoko/parallel_calls/ @dfinity/languages