Skip to content

Commit c168fd1

Browse files
authored
Merge pull request #1316 from dfinity/marc0olo/icp-cli-who-am-i
feat: add icp-cli support to who_am_i (Rust + Motoko)
2 parents 09bff0c + 348953c commit c168fd1

File tree

22 files changed

+493
-377
lines changed

22 files changed

+493
-377
lines changed

motoko/who_am_i/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
src/internet_identity_app_frontend/src/bindings/

motoko/who_am_i/BUILD.md

Lines changed: 11 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,26 @@
11
# Continue building locally
22

3-
Projects deployed through ICP Ninja are temporary; they will only be live for 20 minutes before they are removed. The command-line tool `dfx` can be used to continue building your ICP Ninja project locally and deploy it to the mainnet.
3+
Projects deployed through ICP Ninja are temporary; they will only be live for 30 minutes before they are removed. To continue building locally, follow these steps.
44

5-
To migrate your ICP Ninja project off of the web browser and develop it locally, follow these steps.
5+
### 1. Install developer tools
66

7-
### 1. Install developer tools.
8-
9-
You can install the developer tools natively or use Dev Containers.
10-
11-
#### Option 1: Natively install developer tools
12-
13-
> Installing `dfx` natively is currently only supported on macOS and Linux systems. On Windows, it is recommended to use the Dev Containers option.
14-
15-
1. Install `dfx` with the following command:
16-
17-
```
18-
19-
sh -ci "$(curl -fsSL https://internetcomputer.org/install.sh)"
20-
21-
```
22-
23-
> On Apple Silicon (e.g., Apple M1 chip), make sure you have Rosetta installed (`softwareupdate --install-rosetta`).
24-
25-
2. [Install NodeJS](https://nodejs.org/en/download/package-manager).
26-
27-
3. For Rust projects, you will also need to:
28-
29-
- Install [Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html#install-rust-and-cargo): `curl https://sh.rustup.rs -sSf | sh`
30-
31-
- Install [candid-extractor](https://crates.io/crates/candid-extractor): `cargo install candid-extractor`
32-
33-
4. For Motoko projects, you will also need to:
34-
35-
- Install the Motoko package manager [Mops](https://docs.mops.one/quick-start#2-install-mops-cli): `npm i -g ic-mops`
36-
37-
Lastly, navigate into your project's directory that you downloaded from ICP Ninja.
38-
39-
#### Option 2: Dev Containers
40-
41-
Continue building your projects locally by installing the [Dev Container extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) for VS Code and [Docker](https://docs.docker.com/engine/install/).
42-
43-
Make sure Docker is running, then navigate into your project's directory that you downloaded from ICP Ninja and start the Dev Container by selecting `Dev-Containers: Reopen in Container` in VS Code's command palette (F1 or Ctrl/Cmd+Shift+P).
44-
45-
> Note that local development ports (e.g. the ports used by `dfx` or `vite`) are forwarded from the Dev Container to your local machine. In the VS code terminal, use Ctrl/Cmd+Click on the displayed local URLs to open them in your browser. To view the current port mappings, click the "Ports" tab in the VS Code terminal window.
46-
47-
### 2. Start the local development environment.
48-
49-
```
50-
dfx start --background
51-
```
52-
53-
### 3. Create a local developer identity.
54-
55-
To manage your project's canisters, it is recommended that you create a local [developer identity](https://internetcomputer.org/docs/building-apps/getting-started/identities) rather than use the `dfx` default identity that is not stored securely.
56-
57-
To create a new identity, run the commands:
58-
59-
```
60-
61-
dfx identity new IDENTITY_NAME
62-
63-
dfx identity use IDENTITY_NAME
64-
65-
```
66-
67-
Replace `IDENTITY_NAME` with your preferred identity name. The first command `dfx start --background` starts the local `dfx` processes, then `dfx identity new` will create a new identity and return your identity's seed phase. Be sure to save this in a safe, secure location.
68-
69-
The third command `dfx identity use` will tell `dfx` to use your new identity as the active identity. Any canister smart contracts created after running `dfx identity use` will be owned and controlled by the active identity.
70-
71-
Your identity will have a principal ID associated with it. Principal IDs are used to identify different entities on ICP, such as users and canisters.
72-
73-
[Learn more about ICP developer identities](https://internetcomputer.org/docs/building-apps/getting-started/identities).
74-
75-
### 4. Deploy the project locally.
76-
77-
Deploy your project to your local developer environment with:
78-
79-
```
80-
npm install
81-
dfx deploy
7+
Install [Node.js](https://nodejs.org/en/download/) and [icp-cli](https://cli.internetcomputer.org):
828

9+
```bash
10+
npm install -g @icp-sdk/icp-cli @icp-sdk/ic-wasm
8311
```
8412

85-
Your project will be hosted on your local machine. The local canister URLs for your project will be shown in the terminal window as output of the `dfx deploy` command. You can open these URLs in your web browser to view the local instance of your project.
86-
87-
### 5. Obtain cycles.
88-
89-
To deploy your project to the mainnet for long-term public accessibility, first you will need [cycles](https://internetcomputer.org/docs/building-apps/getting-started/tokens-and-cycles). Cycles are used to pay for the resources your project uses on the mainnet, such as storage and compute.
90-
91-
> This cost model is known as ICP's [reverse gas model](https://internetcomputer.org/docs/building-apps/essentials/gas-cost), where developers pay for their project's gas fees rather than users pay for their own gas fees. This model provides an enhanced end user experience since they do not need to hold tokens or sign transactions when using a dapp deployed on ICP.
92-
93-
> Learn how much a project may cost by using the [pricing calculator](https://internetcomputer.org/docs/building-apps/essentials/cost-estimations-and-examples).
13+
Then navigate into your project's directory that you downloaded from ICP Ninja.
9414

95-
Cycles can be obtained through [converting ICP tokens into cycles using `dfx`](https://internetcomputer.org/docs/building-apps/developer-tools/dfx/dfx-cycles#dfx-cycles-convert).
15+
### 2. Deploy locally
9616

97-
### 6. Deploy to the mainnet.
98-
99-
Once you have cycles, run the command:
100-
101-
```
102-
103-
dfx deploy --network ic
17+
Start the local network and deploy the project:
10418

19+
```bash
20+
icp network start -d
21+
icp deploy
10522
```
10623

107-
After your project has been deployed to the mainnet, it will continuously require cycles to pay for the resources it uses. You will need to [top up](https://internetcomputer.org/docs/building-apps/canister-management/topping-up) your project's canisters or set up automatic cycles management through a service such as [CycleOps](https://cycleops.dev/).
108-
109-
> If your project's canisters run out of cycles, they will be removed from the network.
110-
11124
## Additional examples
11225

11326
Additional code examples and sample applications can be found in the [DFINITY examples repo](https://github.com/dfinity/examples).

motoko/who_am_i/README.md

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,65 @@
11
# Who am I?
22

3+
[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/who_am_i)
4+
5+
## Overview
6+
37
Who am I? demonstrates how entities on the Internet Computer are identified. Every entity, such as a user or canister smart contract, has a principal identifier. Principals can be used for identification and authentication. Who am I? uses Internet Identity (II) for user authentication, then displays the principal identifier associated with that Internet Identity on the user interface.
48

59
## Deploying from ICP Ninja
610

7-
When viewing this project in ICP Ninja, you can deploy it directly to the mainnet for free by clicking "Run" in the upper right corner. Open this project in ICP Ninja:
11+
This example can be deployed directly from [ICP Ninja](https://icp.ninja), a browser-based IDE for ICP. To continue developing locally after deploying from ICP Ninja, see [BUILD.md](BUILD.md).
12+
13+
[![Open in ICP Ninja](https://icp.ninja/assets/open.svg)](https://icp.ninja/i?g=https://github.com/dfinity/examples/motoko/who_am_i)
814

9-
[![](https://icp.ninja/assets/open.svg)](https://icp.ninja/i?g=https://github.com/dfinity/examples/motoko/who_am_i)
15+
> **Note:** ICP Ninja currently uses `dfx` under the hood, which is why this example includes a `dfx.json` configuration file. `dfx` is the legacy CLI, being superseded by [icp-cli](https://cli.internetcomputer.org), which is what developers should use for local development.
1016
11-
## Build and deploy from the command-line
17+
## Build and deploy from the command line
1218

13-
### 1. [Download and install the IC SDK.](https://internetcomputer.org/docs/building-apps/getting-started/install)
19+
### Prerequisites
1420

15-
### 2. Download your project from ICP Ninja using the 'Download files' button on the upper left corner, or [clone the GitHub examples repository.](https://github.com/dfinity/examples/)
21+
- [x] Install [Node.js](https://nodejs.org/en/download/)
22+
- [x] Install [icp-cli](https://cli.internetcomputer.org): `npm install -g @icp-sdk/icp-cli @icp-sdk/ic-wasm`
1623

17-
### 3. Navigate into the project's directory.
24+
### Install
1825

19-
### 4. Deploy the project to your local environment:
26+
Clone the example project:
2027

28+
```bash
29+
git clone https://github.com/dfinity/examples
30+
cd examples/motoko/who_am_i
2131
```
22-
dfx start --background --clean && dfx deploy
32+
33+
### Deployment
34+
35+
Start the local network:
36+
37+
```bash
38+
icp network start -d
39+
```
40+
41+
Deploy the canisters:
42+
43+
```bash
44+
icp deploy
45+
```
46+
47+
Stop the local network when done:
48+
49+
```bash
50+
icp network stop
51+
```
52+
53+
## Updating the Candid interface
54+
55+
The `src/internet_identity_app_backend/internet_identity_app_backend.did` file defines the backend canister's public interface. The frontend TypeScript bindings are auto-generated from this file during the frontend build.
56+
57+
If you modify the backend's public API, regenerate the `.did` file:
58+
59+
```bash
60+
$(mops toolchain bin moc) --idl $(mops sources) -o src/internet_identity_app_backend/internet_identity_app_backend.did src/internet_identity_app_backend/main.mo
2361
```
2462

2563
## Security considerations and best practices
2664

27-
If you base your application on this example, it is recommended that you familiarize yourself with and adhere to the [security best practices](https://internetcomputer.org/docs/building-apps/security/overview) for developing on ICP. This example may not implement all the best practices.
65+
If you base your application on this example, it is recommended that you familiarize yourself with and adhere to the [security best practices](https://docs.internetcomputer.org/building-apps/security/overview) for developing on ICP. This example may not implement all the best practices.

motoko/who_am_i/dfx.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
"canisters": {
33
"internet_identity_app_backend": {
44
"main": "src/internet_identity_app_backend/main.mo",
5-
"type": "motoko",
6-
"args": "--enhanced-orthogonal-persistence"
5+
"type": "motoko"
76
},
87
"internet_identity_app_frontend": {
98
"dependencies": ["internet_identity_app_backend"],

motoko/who_am_i/icp.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
networks:
2+
- name: local
3+
mode: managed
4+
ii: true
5+
6+
canisters:
7+
- name: internet_identity_app_backend
8+
recipe:
9+
type: "@dfinity/motoko@v4.1.0"
10+
configuration:
11+
main: src/internet_identity_app_backend/main.mo
12+
candid: src/internet_identity_app_backend/internet_identity_app_backend.did
13+
14+
- name: internet_identity_app_frontend
15+
recipe:
16+
type: "@dfinity/asset-canister@v2.1.0"
17+
configuration:
18+
dir: src/internet_identity_app_frontend/dist
19+
build:
20+
- npm install --prefix src/internet_identity_app_frontend
21+
- npm run build --prefix src/internet_identity_app_frontend

motoko/who_am_i/mops.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
# Motoko dependencies (https://mops.one/)
1+
[toolchain]
2+
moc = "1.4.1"
23

34
[dependencies]
4-
base = "0.14.9"
5-
core = "1.0.0"
5+
core = "2.3.1"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
service : {
2+
whoami: () -> (principal) query;
3+
}

motoko/who_am_i/src/internet_identity_app_backend/main.mo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import Principal "mo:base/Principal";
1+
import Principal "mo:core/Principal";
22

33
persistent actor Whoami {
44
public query (message) func whoami() : async Principal {

motoko/who_am_i/src/internet_identity_app_frontend/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"private": true,
44
"type": "module",
55
"scripts": {
6-
"prebuild": "npm i --include=dev && dfx generate internet_identity_app_backend",
6+
"prebuild": "npm i --include=dev",
77
"build": "vite build",
88
"dev": "vite"
99
},
@@ -14,10 +14,10 @@
1414
"react-dom": "18.3.1"
1515
},
1616
"devDependencies": {
17+
"@icp-sdk/bindgen": "~0.3.0",
1718
"@types/react": "18.3.12",
1819
"@types/react-dom": "18.3.1",
1920
"@vitejs/plugin-react": "4.3.3",
20-
"vite": "5.4.11",
21-
"vite-plugin-environment": "1.1.3"
21+
"vite": "5.4.11"
2222
}
2323
}

motoko/who_am_i/src/internet_identity_app_frontend/src/App.jsx

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
11
import React, { useState, useEffect } from 'react';
22
import { AuthClient } from '@icp-sdk/auth/client';
3-
import { createActor } from 'declarations/internet_identity_app_backend';
4-
import { canisterId } from 'declarations/internet_identity_app_backend/index.js';
5-
6-
const network = process.env.DFX_NETWORK;
7-
const identityProvider =
8-
network === 'ic'
9-
? 'https://id.ai/' // Mainnet
10-
: 'http://uqzsh-gqaaa-aaaaq-qaada-cai.localhost:4943'; // Local
3+
import { createBackendActor, identityProviderUrl } from './actor';
114

125
// Reusable button component
136
const Button = ({ onClick, children }) => <button onClick={onClick}>{children}</button>;
@@ -28,11 +21,7 @@ const App = () => {
2821
const updateActor = async () => {
2922
const authClient = await AuthClient.create();
3023
const identity = authClient.getIdentity();
31-
const actor = createActor(canisterId, {
32-
agentOptions: {
33-
identity
34-
}
35-
});
24+
const actor = createBackendActor(identity);
3625
const isAuthenticated = await authClient.isAuthenticated();
3726

3827
setState((prev) => ({
@@ -45,7 +34,7 @@ const App = () => {
4534

4635
const login = async () => {
4736
await state.authClient.login({
48-
identityProvider,
37+
identityProvider: identityProviderUrl,
4938
onSuccess: updateActor
5039
});
5140
};

0 commit comments

Comments
 (0)