Background
The vetkeys examples were previously maintained in dfinity/vetkeys and have since moved to this repo. A migration PR (dfinity/vetkeys#366) was developed there but never merged — it was closed when the examples moved. All the work it describes needs to land here instead.
The changes fall into two buckets:
- Bucket 1 — Independent of any library release; can be done now.
- Bucket 2 — Requires `@icp-sdk/vetkeys` 0.5.0 to be published to npm first (tracked in dfinity/vetkeys#384).
Bucket 1 — Can be done now
1. Backend: replace `dfx.json` with `icp.yaml` (all 7 examples)
All 7 example backends currently use `dfx.json`. Replace with `icp.yaml` for all Motoko and Rust backends:
- `basic_bls_signing`
- `basic_ibe`
- `basic_timelock_ibe`
- `encrypted_chat`
- `encrypted_notes_dapp_vetkd`
- `password_manager`
- `password_manager_with_metadata`
Also:
- Update all `Makefile`s to call `icp` instead of `dfx`
- In all `mops.toml` files: pin `moc = "1.5.0"` in a `[toolchain]` section and remove the `--enhanced-orthogonal-persistence` flag from `[moc] args` (it is the default since moc 0.15.0)
- Update Rust backend for `password_manager_with_metadata` to the current `ic-vetkeys` crate interface (the `KeyManager` API changed in 0.5.0)
- Use `test_key_1` instead of `dfx_test_key` in `icp.yaml` configs and canister integration tests (standardise on the icp-cli/PocketIC key name; the library retains backward-compatible handling of `dfx_test_key`)
2. Frontend: replace `@dfinity/*` with `@icp-sdk/core` (all 7 examples)
- Replace `@dfinity/auth-client` with `@icp-sdk/auth`
- Replace `@dfinity/principal`, `@dfinity/agent`, `@dfinity/candid`, `@dfinity/identity` with `@icp-sdk/core` equivalents
- Update all `vite.config.ts` files accordingly
- Update all `gen_bindings.sh` scripts to use `icp-cli` (i.e. call `icp generate` instead of `dfx generate`)
- Add `dev:motoko` / `dev:rust` npm scripts to distinguish which backend to develop against
- Remove deprecated `baseUrl` from `tsconfig.json` in all examples
- Rename `tailwind.config.cjs` → `tailwind.config.mjs` in both `password_manager` examples (required by `"type": "module"`)
- Update `HttpAgent` construction: replace `HttpAgent.createSync()` (deprecated) and `new HttpAgent(options)` (deprecated) with `await HttpAgent.create({ host, identity, ... })`
Important — `gen_bindings.sh` guard: Each example's `gen_bindings.sh` calls `candid-extractor` via a Makefile redirect (`candid-extractor ... > backend.did`). The `>` redirect truncates the `.did` file before the command runs, so if `candid-extractor` is not installed the static `.did` file is silently wiped — causing `bindgen` to read an empty file and generate a `did.js` with no exports, which breaks the Vite build with `"idlFactory" is not exported`. Fix: wrap the extraction call with `if command -v candid-extractor >/dev/null 2>&1` so that the committed `.did` files are left intact when the tool is absent.
3. Frontend source: critical runtime fixes (all affected examples)
These bugs were discovered during testing against the 0.5.0 API. They will cause runtime failures regardless of library version:
- `encrypted_chat` — Fix actor caching in the auth store: actors must be created once on login and cached, not re-created on each call.
- `encrypted_chat` — Fix `DerivedKeyMaterial.fromCryptoKey()` missing `await` (the method is now async).
- `encrypted_chat` — Add the required `associatedData` argument to `encryptMessage()` / `decryptMessage()`.
- `encrypted_notes_dapp_vetkd` — Rewrite `crypto.ts`: `deriveAesGcmCryptoKey()` is now `@internal`; encrypt/decrypt must go through `DerivedKeyMaterial.encryptMessage()` / `decryptMessage()` directly. Additionally, `DerivedKeyMaterial` class instances are not structured-clone safe so they cannot be stored directly in IndexedDB — cache the `CryptoKey` in IndexedDB and reconstruct the `DerivedKeyMaterial` on retrieval via `DerivedKeyMaterial.fromCryptoKey()`.
- All examples — Rename `getBasicIbeCanister` → `getBasicIbeActor` (and equivalent functions in other examples) for naming consistency.
- All examples — Remove the `window.global` polyfill and `as any` casts that were previously required but are no longer needed.
4. CI: update workflows to use icp-cli
- Replace `dfx start` / `dfx deploy` with `icp network start` / `icp deploy` in all example CI workflows
- Remove `DFX_VERSION` env vars; add a Node.js 22 setup step (icp-cli requires Node ≥ 22)
- Update provision scripts (`provision-darwin.sh`, `provision-linux.sh`) to install `icp-cli` instead of `dfx`; also install `ic-mops` globally (required before `icp deploy` for Motoko canisters)
- Use `ICP_CLI_GITHUB_TOKEN` (not `GITHUB_TOKEN`) on all steps that call `icp` — icp-cli uses this specific env var when fetching the network launcher to avoid GitHub rate limits
- Fix flaky `should_access_map_values` integration test: use `BTreeMap` instead of `Vec` for key-value pairs so duplicate key collisions update the expected value correctly rather than causing spurious failures
5. Docs
- Update all `internetcomputer.org/docs/` links → `docs.internetcomputer.org/`
- Replace IC SDK install instructions with ICP CLI references
- Add `icp network stop` instructions to the local deployment sections of all READMEs
- Comment out icp.ninja launch badges for now — icp.ninja currently requires dfx; re-enable once icp.ninja supports icp-cli
- Fix broken anchor in `encrypted_chat/SPEC.md`: `#state-cache` → `#encrypted-symmetric-ratchet-state-cache`
Bucket 2 — Blocked on `@icp-sdk/vetkeys` 0.5.0 npm release
Once dfinity/vetkeys#384 is merged and the `npm/0.5.0` tag is pushed:
- Replace all `@dfinity/vetkeys` references (or local `file:` paths) with `@icp-sdk/vetkeys ^0.5.0` in all 7 example `package.json` files
- Update all `DefaultEncryptedMapsClient` / `DefaultKeyManagerClient` constructor call sites: the constructors now accept an `HttpAgent` directly instead of `HttpAgentOptions` (the agent must be created by the caller via `await HttpAgent.create(...)` before being passed in)
Known pre-existing issues in `encrypted_chat` (not introduced by this migration)
The `encrypted_chat` example is an unfinished prototype (the README carries a disclaimer). The following gaps between `SPEC.md` and the actual implementation predate this migration and should not be fixed as part of this issue — they are called out here for awareness only:
- `get_my_chats_and_time` vs `get_my_chat_ids`: SPEC defines an API returning `{chats, consensus_time_now}` but backend/frontend use `get_my_chat_ids` returning only an array of tuples.
- Extra parameter in create-chat APIs: SPEC says `create_direct_chat(OtherParticipant, SymmetricKeyRotationMins)` but both sides pass `messageExpirationDurationMinutes` as a third parameter.
- `derive_chat_vetkey` VetKeyEpochId: optional in code (`[] | [bigint]`), required in SPEC.
- Nonce type mismatch: SPEC defines `Nonce = blob`, backend DID uses `bigint`.
- 8-byte vs 16-byte nonces: SPEC specifies 16 bytes; frontend uses 8-byte nonces.
Reference
Full context, commit-by-commit breakdown, and the complete diff are in dfinity/vetkeys#366.
Background
The vetkeys examples were previously maintained in
dfinity/vetkeysand have since moved to this repo. A migration PR (dfinity/vetkeys#366) was developed there but never merged — it was closed when the examples moved. All the work it describes needs to land here instead.The changes fall into two buckets:
Bucket 1 — Can be done now
1. Backend: replace `dfx.json` with `icp.yaml` (all 7 examples)
All 7 example backends currently use `dfx.json`. Replace with `icp.yaml` for all Motoko and Rust backends:
Also:
2. Frontend: replace `@dfinity/*` with `@icp-sdk/core` (all 7 examples)
Important — `gen_bindings.sh` guard: Each example's `gen_bindings.sh` calls `candid-extractor` via a Makefile redirect (`candid-extractor ... > backend.did`). The `>` redirect truncates the `.did` file before the command runs, so if `candid-extractor` is not installed the static `.did` file is silently wiped — causing `bindgen` to read an empty file and generate a `did.js` with no exports, which breaks the Vite build with `"idlFactory" is not exported`. Fix: wrap the extraction call with `if command -v candid-extractor >/dev/null 2>&1` so that the committed `.did` files are left intact when the tool is absent.
3. Frontend source: critical runtime fixes (all affected examples)
These bugs were discovered during testing against the 0.5.0 API. They will cause runtime failures regardless of library version:
4. CI: update workflows to use icp-cli
5. Docs
Bucket 2 — Blocked on `@icp-sdk/vetkeys` 0.5.0 npm release
Once dfinity/vetkeys#384 is merged and the `npm/0.5.0` tag is pushed:
Known pre-existing issues in `encrypted_chat` (not introduced by this migration)
The `encrypted_chat` example is an unfinished prototype (the README carries a disclaimer). The following gaps between `SPEC.md` and the actual implementation predate this migration and should not be fixed as part of this issue — they are called out here for awareness only:
Test plan (from dfinity/vetkeys#366)
Reference
Full context, commit-by-commit breakdown, and the complete diff are in dfinity/vetkeys#366.