From ccf46c856a9d56e24172d28c1c38a3a43c4335da Mon Sep 17 00:00:00 2001 From: Marco Walz Date: Fri, 29 May 2026 11:47:34 +0200 Subject: [PATCH 1/2] chore(vetkeys): migrate basic_ibe to icp-cli and @icp-sdk/vetkeys - Replace dfx.json with icp.yaml (Rust and Motoko backends) - Use @icp-sdk/vetkeys@0.5.0-beta.0 instead of @dfinity/vetkeys - Use @icp-sdk/auth@7.1.0 and @icp-sdk/core@5.4.0 - Update Motoko ic-vetkeys to 0.5.0, Rust ic-vetkeys to 0.7.0 - Add moc 1.5.1 toolchain to mops.toml - Replace dfx generate with @icp-sdk/bindgen in gen_bindings.sh - Add CI workflow for both Rust and Motoko backends - Drop icp.ninja support Closes #1343 Co-Authored-By: Claude Sonnet 4.6 --- .../rust-vetkeys-basic-ibe-example.yml | 80 +++++++++++++++++++ rust/vetkeys/basic_ibe/README.md | 28 ++++--- rust/vetkeys/basic_ibe/frontend/package.json | 59 +++++++------- .../frontend/scripts/gen_bindings.sh | 20 ++--- rust/vetkeys/basic_ibe/frontend/src/main.ts | 77 ++++++++++-------- .../vetkeys/basic_ibe/frontend/vite.config.ts | 74 +++++++++++------ rust/vetkeys/basic_ibe/motoko/dfx.json | 49 ------------ rust/vetkeys/basic_ibe/motoko/icp.yaml | 22 +++++ rust/vetkeys/basic_ibe/motoko/mops.toml | 8 +- .../vetkeys/basic_ibe/rust/backend/Cargo.toml | 2 +- rust/vetkeys/basic_ibe/rust/backend/Makefile | 2 +- rust/vetkeys/basic_ibe/rust/dfx.json | 43 ---------- rust/vetkeys/basic_ibe/rust/icp.yaml | 23 ++++++ 13 files changed, 282 insertions(+), 205 deletions(-) create mode 100644 .github/workflows/rust-vetkeys-basic-ibe-example.yml delete mode 100644 rust/vetkeys/basic_ibe/motoko/dfx.json create mode 100644 rust/vetkeys/basic_ibe/motoko/icp.yaml delete mode 100644 rust/vetkeys/basic_ibe/rust/dfx.json create mode 100644 rust/vetkeys/basic_ibe/rust/icp.yaml diff --git a/.github/workflows/rust-vetkeys-basic-ibe-example.yml b/.github/workflows/rust-vetkeys-basic-ibe-example.yml new file mode 100644 index 000000000..113732ea8 --- /dev/null +++ b/.github/workflows/rust-vetkeys-basic-ibe-example.yml @@ -0,0 +1,80 @@ +name: rust-vetkeys-basic-ibe +on: + push: + branches: + - master + pull_request: + paths: + - rust/vetkeys/basic_ibe/** + - .github/workflows/provision-darwin.sh + - .github/workflows/provision-linux.sh + - .github/workflows/rust-vetkeys-basic-ibe-example.yml + - .ic-commit +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true +jobs: + basic-ibe-rust-darwin: + runs-on: macos-15 + steps: + - uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e # v1.2.0 + - name: Provision Darwin + run: bash .github/workflows/provision-darwin.sh + - name: Pre-download network launcher + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: bash .github/workflows/pre-download-launcher.sh + - name: Basic IBE Rust Darwin + run: | + pushd rust/vetkeys/basic_ibe/rust + icp network start -d + icp deploy + popd + basic-ibe-rust-linux: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e # v1.2.0 + - name: Provision Linux + run: bash .github/workflows/provision-linux.sh + - name: Pre-download network launcher + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: bash .github/workflows/pre-download-launcher.sh + - name: Basic IBE Rust Linux + run: | + pushd rust/vetkeys/basic_ibe/rust + icp network start -d + icp deploy + popd + basic-ibe-motoko-darwin: + runs-on: macos-15 + steps: + - uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e # v1.2.0 + - name: Provision Darwin + run: bash .github/workflows/provision-darwin.sh + - name: Pre-download network launcher + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: bash .github/workflows/pre-download-launcher.sh + - name: Basic IBE Motoko Darwin + run: | + pushd rust/vetkeys/basic_ibe/motoko + icp network start -d + icp deploy + popd + basic-ibe-motoko-linux: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e # v1.2.0 + - name: Provision Linux + run: bash .github/workflows/provision-linux.sh + - name: Pre-download network launcher + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: bash .github/workflows/pre-download-launcher.sh + - name: Basic IBE Motoko Linux + run: | + pushd rust/vetkeys/basic_ibe/motoko + icp network start -d + icp deploy + popd diff --git a/rust/vetkeys/basic_ibe/README.md b/rust/vetkeys/basic_ibe/README.md index 9882742b6..e384e222f 100644 --- a/rust/vetkeys/basic_ibe/README.md +++ b/rust/vetkeys/basic_ibe/README.md @@ -1,10 +1,12 @@ # Identity-Based Encryption + -The **Basic IBE** example demonstrates how to use **[VetKeys](https://internetcomputer.org/docs/building-apps/network-features/vetkeys/introduction)** to implement secure messaging between users by means of Identity-Based Encryption (IBE) on the **Internet Computer (IC)**. This application allows users to send encrypted messages to other users using their **Internet Identity Principal** as the encryption key identifier. This canister (IC smart contract) ensures that only the authorized user can access their private decryption key, meaning that even if someone else knows your principal, they cannot decrypt messages intended for you because neither other users nor this canister can access your private key. +The **Basic IBE** example demonstrates how to use **[VetKeys](https://docs.internetcomputer.org/building-apps/network-features/vetkeys/introduction)** to implement secure messaging between users by means of Identity-Based Encryption (IBE) on the **Internet Computer (IC)**. This application allows users to send encrypted messages to other users using their **Internet Identity Principal** as the encryption key identifier. This canister (IC smart contract) ensures that only the authorized user can access their private decryption key, meaning that even if someone else knows your principal, they cannot decrypt messages intended for you because neither other users nor this canister can access your private key. Note that generally it is possible for a canister to request a decryption key to decrypt secrets as part of its code. However, doing so requires the canister to provide its own transport key instead of requesting a user's transport key and this inherently makes secrets public. @@ -22,23 +24,33 @@ A canister functionality for decrypting secrets can be detected by inspecting th ### Prerequisites -- [Internet Computer software development kit](https://internetcomputer.org/docs/building-apps/getting-started/install) +- [ICP CLI](https://cli.internetcomputer.org) - [npm](https://www.npmjs.com/package/npm) ### (Optionally) Choose a Different Master Key -This example uses `test_key_1` by default. To use a different [available master key](https://internetcomputer.org/docs/building-apps/network-features/vetkeys/api#available-master-keys), change the `"init_arg": "(\"test_key_1\")"` line in `dfx.json` to the desired key before running `dfx deploy` in the next step. +This example uses `test_key_1` by default. To use a different [available master key](https://docs.internetcomputer.org/building-apps/network-features/vetkeys/api#available-master-keys), change the `init_args` value in `icp.yaml` to the desired key before running `icp deploy` in the next step. ### Deploy the Canisters Locally If you want to deploy this project locally with a Motoko backend, then run: ```bash -dfx start --background && dfx deploy +icp network start -d && icp deploy ``` from the `motoko` folder. To use the Rust backend instead of Motoko, run the same command in the `rust` folder. +To run the frontend in development mode with hot reloading (after running `icp deploy`): +```bash +npm run dev +``` + +When you are done testing, stop the local network to free up resources and unblock the default port for other projects: +```bash +icp network stop +``` + ## Example Components ### Backend @@ -52,16 +64,10 @@ The backend consists of a canister that: The frontend is a vanilla typescript application providing a simple interface for sending, receiving, and deleting encrypted messages. -To run the frontend in development mode with hot reloading (after running `dfx deploy`): - -```bash -npm run dev -``` - ## Limitations This example dapp does not implement key rotation, which is strongly recommended in a production dapp to limit the impact of potential key compromise if a malicious party gains access to the user's decryption key. ## Additional Resources -- **[What are VetKeys](https://internetcomputer.org/docs/building-apps/network-features/vetkeys/introduction)** - For more information about VetKeys and VetKD. +- **[What are VetKeys](https://docs.internetcomputer.org/building-apps/network-features/vetkeys/introduction)** - For more information about VetKeys and VetKD. diff --git a/rust/vetkeys/basic_ibe/frontend/package.json b/rust/vetkeys/basic_ibe/frontend/package.json index ca7932ea7..3513a48db 100644 --- a/rust/vetkeys/basic_ibe/frontend/package.json +++ b/rust/vetkeys/basic_ibe/frontend/package.json @@ -1,31 +1,32 @@ { - "name": "basic-ibe-frontend", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "dev": "npm run build:bindings && vite", - "build": "npm run build:bindings && tsc && vite build", - "build:bindings": "cd scripts && ./gen_bindings.sh", - "preview": "vite preview", - "lint": "eslint" - }, - "devDependencies": { - "@eslint/js": "^9.24.0", - "@rollup/plugin-typescript": "^12.1.2", - "@types/node": "^24.0.4", - "eslint": "^9.24.0", - "eslint-config-prettier": "^10.1.5", - "eslint-plugin-prettier": "^5.4.0", - "tslib": "^2.8.1", - "typescript": "~5.7.2", - "typescript-eslint": "^8.35.1", - "vite": "^6.4.1", - "vite-plugin-environment": "^1.1.3" - }, - "dependencies": { - "@dfinity/auth-client": "^2.4.1", - "@dfinity/principal": "^2.4.1", - "@dfinity/vetkeys": "^0.3.0" - } + "name": "basic-ibe-frontend", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "printf '\\nNo backend specified. Use one of:\\n\\n npm run dev:motoko\\n npm run dev:rust\\n\\n' && exit 1", + "dev:motoko": "npm run build:bindings && BACKEND=motoko vite", + "dev:rust": "npm run build:bindings && BACKEND=rust vite", + "build": "npm run build:bindings && tsc && vite build", + "build:bindings": "cd scripts && ./gen_bindings.sh", + "preview": "vite preview", + "lint": "eslint" + }, + "devDependencies": { + "@eslint/js": "^9.24.0", + "@rollup/plugin-typescript": "^12.1.2", + "@types/node": "^24.0.10", + "eslint": "^9.24.0", + "eslint-config-prettier": "^10.1.5", + "eslint-plugin-prettier": "^5.4.0", + "tslib": "^2.8.1", + "typescript": "~5.7.2", + "typescript-eslint": "^8.35.1", + "vite": "^6.4.1" + }, + "dependencies": { + "@icp-sdk/auth": "^7.1.0", + "@icp-sdk/core": "^5.4.0", + "@icp-sdk/vetkeys": "^0.5.0-beta.0" + } } diff --git a/rust/vetkeys/basic_ibe/frontend/scripts/gen_bindings.sh b/rust/vetkeys/basic_ibe/frontend/scripts/gen_bindings.sh index 91ce67a86..f12cd9abb 100755 --- a/rust/vetkeys/basic_ibe/frontend/scripts/gen_bindings.sh +++ b/rust/vetkeys/basic_ibe/frontend/scripts/gen_bindings.sh @@ -1,15 +1,15 @@ #!/bin/bash -cd ../../backend && make extract-candid +# Bindings are always generated from the Rust backend since both backends +# expose the same Candid interface. +if command -v candid-extractor >/dev/null 2>&1; then + cd ../../rust/backend && make extract-candid + cd ../.. +else + cd ../.. +fi -cd .. && dfx generate basic_ibe || exit 1 - -rm -r frontend/src/declarations/basic_ibe > /dev/null 2>&1 || true +rm -rf frontend/src/declarations/basic_ibe mkdir -p frontend/src/declarations/basic_ibe -mv src/declarations/basic_ibe frontend/src/declarations -rmdir -p src/declarations > /dev/null 2>&1 || true - -# dfx 0.31+ generates @icp-sdk/core imports; rewrite to @dfinity/* to match deps -find frontend/src/declarations -type f \( -name '*.ts' -o -name '*.js' \) -exec \ - perl -i -pe 's|\@icp-sdk/core/agent|\@dfinity/agent|g; s|\@icp-sdk/core/principal|\@dfinity/principal|g; s|\@icp-sdk/core/candid|\@dfinity/candid|g' {} + \ No newline at end of file +npx @icp-sdk/bindgen --did-file rust/backend/backend.did --out-dir frontend/src/declarations/basic_ibe --declarations-flat --force diff --git a/rust/vetkeys/basic_ibe/frontend/src/main.ts b/rust/vetkeys/basic_ibe/frontend/src/main.ts index d15d165f5..0bef2fc07 100644 --- a/rust/vetkeys/basic_ibe/frontend/src/main.ts +++ b/rust/vetkeys/basic_ibe/frontend/src/main.ts @@ -1,6 +1,6 @@ import "./style.css"; -import { createActor } from "./declarations/basic_ibe"; -import { Principal } from "@dfinity/principal"; +import { idlFactory } from "./declarations/basic_ibe/backend.did"; +import { Principal } from "@icp-sdk/core/principal"; import { TransportSecretKey, DerivedPublicKey, @@ -9,44 +9,49 @@ import { IbeCiphertext, IbeIdentity, IbeSeed, -} from "@dfinity/vetkeys"; -import { Inbox, _SERVICE } from "./declarations/basic_ibe/basic_ibe.did"; -import { AuthClient } from "@dfinity/auth-client"; -import type { ActorSubclass } from "@dfinity/agent"; +} from "@icp-sdk/vetkeys"; +import { Inbox, _SERVICE } from "./declarations/basic_ibe/backend.did"; +import { AuthClient } from "@icp-sdk/auth/client"; +import { Actor, HttpAgent, type ActorSubclass } from "@icp-sdk/core/agent"; +import { safeGetCanisterEnv } from "@icp-sdk/core/agent/canister-env"; + +const canisterEnv = safeGetCanisterEnv<{ + "PUBLIC_CANISTER_ID:basic_ibe": string; +}>(); let ibePrivateKey: VetKey | undefined = undefined; let ibePublicKey: DerivedPublicKey | undefined = undefined; let myPrincipal: Principal | undefined = undefined; let authClient: AuthClient | undefined; -let basicIbeCanister: ActorSubclass<_SERVICE> | undefined; +let basicIbeActor: ActorSubclass<_SERVICE> | undefined; -function getBasicIbeCanister(): ActorSubclass<_SERVICE> { - if (basicIbeCanister) return basicIbeCanister; - if (!process.env.CANISTER_ID_BASIC_IBE) { - throw Error("CANISTER_ID_BASIC_IBE is not set"); +async function getBasicIbeActor(): Promise> { + if (basicIbeActor) return basicIbeActor; + const canisterId = canisterEnv?.["PUBLIC_CANISTER_ID:basic_ibe"]; + if (!canisterId) { + throw Error("Canister ID for basic_ibe is not set"); } if (!authClient) { throw Error("Auth client is not initialized"); } - const host = - process.env.DFX_NETWORK === "ic" - ? `https://${process.env.CANISTER_ID_BASIC_IBE}.ic0.app` - : "http://localhost:8000"; - - basicIbeCanister = createActor(process.env.CANISTER_ID_BASIC_IBE, { - agentOptions: { - identity: authClient.getIdentity(), - host, - }, + + const agent = await HttpAgent.create({ + identity: authClient.getIdentity(), + host: window.location.origin, + ...(canisterEnv?.IC_ROOT_KEY + ? { rootKey: canisterEnv.IC_ROOT_KEY } + : {}), }); + basicIbeActor = Actor.createActor(idlFactory, { agent, canisterId }); - return basicIbeCanister!; + return basicIbeActor; } async function getIbePublicKey(): Promise { if (ibePublicKey) return ibePublicKey; + const actor = await getBasicIbeActor(); ibePublicKey = DerivedPublicKey.deserialize( - new Uint8Array(await getBasicIbeCanister().get_ibe_public_key()), + new Uint8Array(await actor.get_ibe_public_key()), ); return ibePublicKey; } @@ -72,8 +77,9 @@ async function getMyIbePrivateKey(): Promise { throw Error("My principal is not set"); } else { const transportSecretKey = TransportSecretKey.random(); + const actor = await getBasicIbeActor(); const encryptedKey = Uint8Array.from( - await getBasicIbeCanister().get_my_encrypted_ibe_key( + await actor.get_my_encrypted_ibe_key( transportSecretKey.publicKeyBytes(), ), ); @@ -110,7 +116,8 @@ async function sendMessage() { receiverPrincipal, ); - const result = await getBasicIbeCanister().send_message({ + const actor = await getBasicIbeActor(); + const result = await actor.send_message({ encrypted_message: encryptedMessage, receiver: receiverPrincipal, }); @@ -126,7 +133,8 @@ async function sendMessage() { } async function showMessages() { - const inbox = await getBasicIbeCanister().get_my_messages(); + const actor = await getBasicIbeActor(); + const inbox = await actor.get_my_messages(); await displayMessages(inbox); } @@ -219,10 +227,10 @@ async function displayMessages(inbox: Inbox) { void (async () => { try { - const result = - await getBasicIbeCanister().remove_my_message_by_index( - BigInt(index), - ); + const actor = await getBasicIbeActor(); + const result = await actor.remove_my_message_by_index( + BigInt(index), + ); if ("Err" in result) { alert("Error deleting message: " + result.Err); } else { @@ -243,9 +251,10 @@ export function login(client: AuthClient) { void client.login({ maxTimeToLive: BigInt(1800) * BigInt(1_000_000_000), identityProvider: - process.env.DFX_NETWORK === "ic" - ? "https://identity.ic0.app/#authorize" - : `http://rdmx6-jaaaa-aaaaa-aaadq-cai.localhost:8000/#authorize`, + window.location.hostname === "localhost" || + window.location.hostname.endsWith(".localhost") + ? `http://id.ai.localhost:8000/#authorize` + : "https://identity.ic0.app/#authorize", onSuccess: () => { myPrincipal = client.getIdentity().getPrincipal(); updateUI(true); @@ -262,7 +271,7 @@ export function logout() { messagesDiv.innerHTML = ""; ibePrivateKey = undefined; myPrincipal = undefined; - basicIbeCanister = undefined; + basicIbeActor = undefined; updateUI(false); } diff --git a/rust/vetkeys/basic_ibe/frontend/vite.config.ts b/rust/vetkeys/basic_ibe/frontend/vite.config.ts index 27bf81575..be565c163 100644 --- a/rust/vetkeys/basic_ibe/frontend/vite.config.ts +++ b/rust/vetkeys/basic_ibe/frontend/vite.config.ts @@ -1,27 +1,51 @@ -import { defineConfig } from 'vite' -import typescript from '@rollup/plugin-typescript'; -import environment from 'vite-plugin-environment'; -import path from 'path'; +import { defineConfig } from "vite"; +import { execSync } from "child_process"; -// https://vite.dev/config/ -export default defineConfig({ - plugins: [ - typescript({ - inlineSources: true, - }), - environment("all", { prefix: "CANISTER_" }), - environment("all", { prefix: "DFX_" }), - ], - build: { - sourcemap: true, - rollupOptions: { - output: { - inlineDynamicImports: true, - }, +const environment = process.env.ICP_ENVIRONMENT || "local"; +const CANISTER_NAMES = ["basic_ibe"]; + +function getDevServerConfig() { + const backend = process.env.BACKEND; + if (!backend) { + throw new Error( + "BACKEND env var is required. Use `npm run dev:motoko` or `npm run dev:rust`.", + ); + } + + const networkStatus = JSON.parse( + execSync(`icp network status -e ${environment} --json --project-root-override ../${backend}`, { + encoding: "utf-8", + }), + ); + const canisterParams = CANISTER_NAMES.map((name) => { + const id = execSync( + `icp canister status ${name} -e ${environment} --id-only --project-root-override ../${backend}`, + { encoding: "utf-8", stdio: "pipe" }, + ).trim(); + return `PUBLIC_CANISTER_ID:${name}=${id}`; + }).join("&"); + return { + headers: { + "Set-Cookie": `ic_env=${encodeURIComponent( + `${canisterParams}&ic_root_key=${networkStatus.root_key}`, + )}; SameSite=Lax;`, + }, + proxy: { + "/api": { target: networkStatus.api_url, changeOrigin: true }, + }, + hmr: false, + }; +} + +export default defineConfig(({ command }) => ({ + build: { + sourcemap: true, + rollupOptions: { + output: { + inlineDynamicImports: true, + }, + }, }, - }, - root: "./", - server: { - hmr: false - } -}) \ No newline at end of file + root: "./", + ...(command === "serve" ? { server: getDevServerConfig() } : {}), +})); diff --git a/rust/vetkeys/basic_ibe/motoko/dfx.json b/rust/vetkeys/basic_ibe/motoko/dfx.json deleted file mode 100644 index 438929689..000000000 --- a/rust/vetkeys/basic_ibe/motoko/dfx.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "canisters": { - "basic_ibe": { - "main": "backend/src/Main.mo", - "type": "motoko", - "args": "--enhanced-orthogonal-persistence", - "init_arg": "(\"test_key_1\")", - "metadata": [ - { - "name": "candid:service", - "visibility": "public" - } - ] - }, - "internet-identity": { - "candid": "https://github.com/dfinity/internet-identity/releases/download/release-2026-03-16/internet_identity.did", - "type": "custom", - "specified_id": "rdmx6-jaaaa-aaaaa-aaadq-cai", - "remote": { - "id": { - "ic": "rdmx6-jaaaa-aaaaa-aaadq-cai" - } - }, - "wasm": "https://github.com/dfinity/internet-identity/releases/download/release-2026-03-16/internet_identity_dev.wasm.gz" - }, - "www": { - "dependencies": ["basic_ibe", "internet-identity"], - "build": ["cd frontend && npm i --include=dev && npm run build && cd - && rm -r dist > /dev/null 2>&1; mv frontend/dist ./"], - "frontend": { - "entrypoint": "dist/index.html" - }, - "source": ["dist/"], - "type": "assets", - "output_env_file": "frontend/.env" - } - }, - "defaults": { - "build": { - "packtool": "npx ic-mops sources", - "args": "" - } - }, - "networks": { - "local": { - "bind": "127.0.0.1:8000", - "type": "ephemeral" - } - } - } \ No newline at end of file diff --git a/rust/vetkeys/basic_ibe/motoko/icp.yaml b/rust/vetkeys/basic_ibe/motoko/icp.yaml new file mode 100644 index 000000000..f299d64ab --- /dev/null +++ b/rust/vetkeys/basic_ibe/motoko/icp.yaml @@ -0,0 +1,22 @@ +canisters: + - name: basic_ibe + recipe: + type: "@dfinity/motoko@v4.1.0" + configuration: + main: backend/src/Main.mo + init_args: + type: text + value: "(\"test_key_1\")" + + - name: www + recipe: + type: "@dfinity/asset-canister@v2.1.0" + configuration: + dir: dist + build: + - cd frontend && npm i --include=dev && npm run build && cd - && rm -rf dist; mv frontend/dist ./ + +networks: + - name: local + mode: managed + ii: true diff --git a/rust/vetkeys/basic_ibe/motoko/mops.toml b/rust/vetkeys/basic_ibe/motoko/mops.toml index 7de5a57da..2d851a475 100644 --- a/rust/vetkeys/basic_ibe/motoko/mops.toml +++ b/rust/vetkeys/basic_ibe/motoko/mops.toml @@ -1,3 +1,7 @@ +[toolchain] +moc = "1.5.1" + [dependencies] -core = "1.0.0" -ic-vetkeys = "0.3.0" +core = "2.4.0" +ic-vetkeys = "0.5.0" +sha2 = "0.1.14" diff --git a/rust/vetkeys/basic_ibe/rust/backend/Cargo.toml b/rust/vetkeys/basic_ibe/rust/backend/Cargo.toml index 3a46c29ca..7b63bd44c 100644 --- a/rust/vetkeys/basic_ibe/rust/backend/Cargo.toml +++ b/rust/vetkeys/basic_ibe/rust/backend/Cargo.toml @@ -17,7 +17,7 @@ candid = "0.10.2" ic-cdk = "0.18.3" ic-dummy-getrandom-for-wasm = "0.1.0" ic-stable-structures = "0.6.8" -ic-vetkeys = "0.3.0" +ic-vetkeys = "0.7.0" serde = "1.0.217" serde_bytes = "0.11.15" serde_cbor = "0.11.2" diff --git a/rust/vetkeys/basic_ibe/rust/backend/Makefile b/rust/vetkeys/basic_ibe/rust/backend/Makefile index dc7cfae2d..766c349bf 100644 --- a/rust/vetkeys/basic_ibe/rust/backend/Makefile +++ b/rust/vetkeys/basic_ibe/rust/backend/Makefile @@ -12,4 +12,4 @@ extract-candid: compile-wasm .SILENT: clean clean: cargo clean - rm -rf ../dfx \ No newline at end of file + rm -rf ../.icp \ No newline at end of file diff --git a/rust/vetkeys/basic_ibe/rust/dfx.json b/rust/vetkeys/basic_ibe/rust/dfx.json deleted file mode 100644 index 09ba32f7e..000000000 --- a/rust/vetkeys/basic_ibe/rust/dfx.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "canisters": { - "basic_ibe": { - "candid": "backend/backend.did", - "package": "ic-vetkd-example-basic-ibe-backend", - "type": "rust", - "init_arg": "(\"test_key_1\")", - "metadata": [ - { - "name": "candid:service", - "visibility": "public" - } - ] - }, - "internet-identity": { - "candid": "https://github.com/dfinity/internet-identity/releases/download/release-2026-03-16/internet_identity.did", - "type": "custom", - "specified_id": "rdmx6-jaaaa-aaaaa-aaadq-cai", - "remote": { - "id": { - "ic": "rdmx6-jaaaa-aaaaa-aaadq-cai" - } - }, - "wasm": "https://github.com/dfinity/internet-identity/releases/download/release-2026-03-16/internet_identity_dev.wasm.gz" - }, - "www": { - "dependencies": ["basic_ibe", "internet-identity"], - "build": ["cd frontend && npm i --include=dev && npm run build && cd - && rm -r dist > /dev/null 2>&1; mv frontend/dist ./"], - "frontend": { - "entrypoint": "dist/index.html" - }, - "source": ["dist/"], - "type": "assets", - "output_env_file": "frontend/.env" - } - }, - "networks": { - "local": { - "bind": "127.0.0.1:8000", - "type": "ephemeral" - } - } - } \ No newline at end of file diff --git a/rust/vetkeys/basic_ibe/rust/icp.yaml b/rust/vetkeys/basic_ibe/rust/icp.yaml new file mode 100644 index 000000000..898769bf2 --- /dev/null +++ b/rust/vetkeys/basic_ibe/rust/icp.yaml @@ -0,0 +1,23 @@ +canisters: + - name: basic_ibe + recipe: + type: "@dfinity/rust@v3.2.0" + configuration: + package: ic-vetkd-example-basic-ibe-backend + candid: backend/backend.did + init_args: + type: text + value: "(\"test_key_1\")" + + - name: www + recipe: + type: "@dfinity/asset-canister@v2.1.0" + configuration: + dir: dist + build: + - cd frontend && npm i --include=dev && npm run build && cd - && rm -rf dist; mv frontend/dist ./ + +networks: + - name: local + mode: managed + ii: true From cc5dfba6fbb0f9baff6f5b22414bddf60bc3acbe Mon Sep 17 00:00:00 2001 From: Marco Walz Date: Sat, 30 May 2026 04:13:25 +0200 Subject: [PATCH 2/2] fix(ci): update basic_ibe to use ic-cdk 0.20.1 and @icp-sdk/auth@7.1.0 API - Remove rust-toolchain channel pin and profile (fixes cargo component error) - Bump ic-cdk to 0.20.1 and add ic-cdk-management-canister 0.1.1 - Update ic_cdk::management_canister imports to ic_cdk_management_canister - Update AuthClient API: constructor, signIn/signOut, async getIdentity Co-Authored-By: Claude Sonnet 4.6 --- rust/vetkeys/basic_ibe/frontend/src/main.ts | 45 ++++++++++--------- .../vetkeys/basic_ibe/rust/backend/Cargo.toml | 3 +- .../vetkeys/basic_ibe/rust/backend/src/lib.rs | 6 +-- .../basic_ibe/rust/rust-toolchain.toml | 4 +- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/rust/vetkeys/basic_ibe/frontend/src/main.ts b/rust/vetkeys/basic_ibe/frontend/src/main.ts index 0bef2fc07..11a456584 100644 --- a/rust/vetkeys/basic_ibe/frontend/src/main.ts +++ b/rust/vetkeys/basic_ibe/frontend/src/main.ts @@ -36,7 +36,7 @@ async function getBasicIbeActor(): Promise> { } const agent = await HttpAgent.create({ - identity: authClient.getIdentity(), + identity: await authClient.getIdentity(), host: window.location.origin, ...(canisterEnv?.IC_ROOT_KEY ? { rootKey: canisterEnv.IC_ROOT_KEY } @@ -247,26 +247,20 @@ async function displayMessages(inbox: Inbox) { }); } -export function login(client: AuthClient) { - void client.login({ - maxTimeToLive: BigInt(1800) * BigInt(1_000_000_000), - identityProvider: - window.location.hostname === "localhost" || - window.location.hostname.endsWith(".localhost") - ? `http://id.ai.localhost:8000/#authorize` - : "https://identity.ic0.app/#authorize", - onSuccess: () => { - myPrincipal = client.getIdentity().getPrincipal(); - updateUI(true); - }, - onError: (error) => { - alert("Authentication failed: " + error); - }, - }); +export async function login(client: AuthClient): Promise { + try { + const identity = await client.signIn({ + maxTimeToLive: BigInt(1800) * BigInt(1_000_000_000), + }); + myPrincipal = identity.getPrincipal(); + updateUI(true); + } catch (error: unknown) { + alert("Authentication failed: " + error); + } } export function logout() { - void authClient?.logout(); + void authClient?.signOut(); const messagesDiv = document.getElementById("messages")!; messagesDiv.innerHTML = ""; ibePrivateKey = undefined; @@ -276,11 +270,18 @@ export function logout() { } async function initAuth() { - authClient = await AuthClient.create(); - const isAuthenticated = await authClient.isAuthenticated(); + const isLocal = + window.location.hostname === "localhost" || + window.location.hostname.endsWith(".localhost"); + authClient = new AuthClient({ + identityProvider: isLocal + ? "http://id.ai.localhost:8000/#authorize" + : undefined, + }); + const isAuthenticated = authClient.isAuthenticated(); if (isAuthenticated) { - myPrincipal = authClient.getIdentity().getPrincipal(); + myPrincipal = (await authClient.getIdentity()).getPrincipal(); updateUI(true); } else { updateUI(false); @@ -309,7 +310,7 @@ function handleLogin() { return; } - login(authClient); + void login(authClient); } document.querySelector("#app")!.innerHTML = ` diff --git a/rust/vetkeys/basic_ibe/rust/backend/Cargo.toml b/rust/vetkeys/basic_ibe/rust/backend/Cargo.toml index 7b63bd44c..8d9be7a0f 100644 --- a/rust/vetkeys/basic_ibe/rust/backend/Cargo.toml +++ b/rust/vetkeys/basic_ibe/rust/backend/Cargo.toml @@ -14,7 +14,8 @@ crate-type = ["cdylib"] [dependencies] candid = "0.10.2" -ic-cdk = "0.18.3" +ic-cdk = "0.20.1" +ic-cdk-management-canister = "0.1.1" ic-dummy-getrandom-for-wasm = "0.1.0" ic-stable-structures = "0.6.8" ic-vetkeys = "0.7.0" diff --git a/rust/vetkeys/basic_ibe/rust/backend/src/lib.rs b/rust/vetkeys/basic_ibe/rust/backend/src/lib.rs index be32c1118..890dd5402 100644 --- a/rust/vetkeys/basic_ibe/rust/backend/src/lib.rs +++ b/rust/vetkeys/basic_ibe/rust/backend/src/lib.rs @@ -1,5 +1,5 @@ use candid::Principal; -use ic_cdk::management_canister::{VetKDCurve, VetKDDeriveKeyArgs, VetKDKeyId, VetKDPublicKeyArgs}; +use ic_cdk_management_canister::{VetKDCurve, VetKDDeriveKeyArgs, VetKDKeyId, VetKDPublicKeyArgs}; use ic_cdk::{init, query, update}; use ic_stable_structures::memory_manager::{MemoryId, MemoryManager, VirtualMemory}; use ic_stable_structures::{BTreeMap as StableBTreeMap, Cell as StableCell, DefaultMemoryImpl}; @@ -75,7 +75,7 @@ async fn get_ibe_public_key() -> VetKeyPublicKey { key_id: key_id(), }; - let result = ic_cdk::management_canister::vetkd_public_key(&request) + let result = ic_cdk_management_canister::vetkd_public_key(&request) .await .expect("call to vetkd_public_key failed"); @@ -93,7 +93,7 @@ async fn get_my_encrypted_ibe_key(transport_key: TransportPublicKey) -> Encrypte transport_public_key: transport_key.into_vec(), }; - let result = ic_cdk::management_canister::vetkd_derive_key(&request) + let result = ic_cdk_management_canister::vetkd_derive_key(&request) .await .expect("call to vetkd_derive_key failed"); diff --git a/rust/vetkeys/basic_ibe/rust/rust-toolchain.toml b/rust/vetkeys/basic_ibe/rust/rust-toolchain.toml index 2a2058b04..6e5beca4f 100644 --- a/rust/vetkeys/basic_ibe/rust/rust-toolchain.toml +++ b/rust/vetkeys/basic_ibe/rust/rust-toolchain.toml @@ -1,4 +1,2 @@ [toolchain] -channel = "1.88.0" -targets = ["wasm32-unknown-unknown"] -profile = "default" \ No newline at end of file +targets = ["wasm32-unknown-unknown"] \ No newline at end of file