Skip to content

chore(vetkeys): split password_manager_with_metadata into self-contained motoko + rust examples#1447

Open
marc0olo wants to merge 7 commits into
masterfrom
chore/split-vetkeys-password-manager-with-metadata
Open

chore(vetkeys): split password_manager_with_metadata into self-contained motoko + rust examples#1447
marc0olo wants to merge 7 commits into
masterfrom
chore/split-vetkeys-password-manager-with-metadata

Conversation

@marc0olo

Copy link
Copy Markdown
Member

Summary

Splits the vetkeys password_manager_with_metadata example into two self-contained examples (one per language) — same restructure as #1443#1446, and the last of the vetkeys split series. Previously it lived only under rust/vetkeys/password_manager_with_metadata/ with a shared Svelte frontend symlinked into motoko/ and rust/ subdirs.

motoko/vetkeys/password_manager_with_metadata/   backend/app.mo + own frontend/ + icp.yaml + mops.toml
rust/vetkeys/password_manager_with_metadata/      backend/ (flattened) + own frontend/ + icp.yaml + Cargo.toml

Why this one is a hybrid (bindgen, but no camelCase)

This example has a custom backend (metadata methods) that the frontend calls via generated bindings (password_manager.ts builds an actor from idlFactory), plus the @icp-sdk/vetkeys Encrypted Maps client for the crypto ops. Because the SDK client calls the Encrypted Maps interface snake_case, the backend interface is kept snake_case (no camelCase), while the custom actor still needs icpBindgen.

Changes

  • Frontend (Svelte): per-language copy (identical); bindings via the @icp-sdk/bindgen Vite plugin from the committed backend/backend.did (replaces scripts/gen_bindings.sh); declaration imports repointed to ../bindings/…; canister renamed to backend (env key PUBLIC_CANISTER_ID:backend); dropped eslint/prettier and a stray save dependency; kept the @dfinity/vetkeys@icp-sdk/vetkeys vite alias; root workspace package.json so npm run dev runs from the example root.
  • Motoko: moc 1.11.0 + --default-persistent-actors (dropped persistent); committed backend/backend.did.
  • Rust: unchanged; relocated (the .did was already backend/backend.did).
  • README split per language (linked prerequisites); test.sh added (query method called with --query); vetkeys-password-manager-with-metadata.yml split into motoko + rust jobs.

CODEOWNERS

Unchanged — /motoko/vetkeys/ and /rust/vetkeys/ both map to @dfinity/core-protocol.

Verification (local)

  • Motoko: vite build (icpBindgen) + deploy, test.sh PASS, and a value survives an upgrade.
  • Rust: cargo/wasm build + deploy, test.sh PASS.
  • Both frontends build and serve.

Completes the vetkeys split series: #1443 (basic_ibe), #1444 (basic_bls_signing), #1445 (encrypted_notes_app_vetkd), #1446 (password_manager), and this one.

🤖 Generated with Claude Code

marc0olo and others added 5 commits July 16, 2026 18:05
…ned motoko + rust examples

Same split as the earlier vetkeys examples (#1443#1446): move the Motoko
variant to motoko/vetkeys/password_manager_with_metadata and flatten the Rust
variant to rust/vetkeys/password_manager_with_metadata, each self-contained
with its own frontend copy (previously a shared Svelte frontend symlinked into
motoko/ and rust/ subdirs).

This example is a hybrid: a custom backend (metadata methods) accessed via
generated bindings, PLUS the @icp-sdk/vetkeys Encrypted Maps client for the
crypto ops. Because the SDK client calls the Encrypted Maps interface
snake_case, the backend interface is kept snake_case (no camelCase), but the
custom actor still needs bindgen.

- Frontend (Svelte): per-language copy (identical); bindings via the
  @icp-sdk/bindgen Vite plugin from the committed backend/backend.did (replaces
  scripts/gen_bindings.sh); declaration imports repointed to ../bindings/…;
  canister renamed to `backend` (env key PUBLIC_CANISTER_ID:backend); dropped
  eslint/prettier + the bogus `save` dep; kept the @dfinity/vetkeys ->
  @icp-sdk/vetkeys vite alias; root workspace package.json so `npm run dev` runs
  from the example root.
- Motoko: moc 1.11.0 + --default-persistent-actors (dropped `persistent`);
  committed backend/backend.did.
- Rust: unchanged; relocated (the .did was already backend/backend.did).
- READMEs split per language (linked prerequisites); test.sh added (query method
  called with --query); CI split into motoko + rust jobs.

CODEOWNERS unchanged: /motoko/vetkeys/ and /rust/vetkeys/ both map to
@dfinity/core-protocol.

Verified: Motoko deploy + test.sh + a value survives an upgrade; Rust cargo
build + deploy + test.sh; both frontends build/serve.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rface + note the mixin

Same rationale as password_manager: the Encrypted Maps methods must stay
snake_case because the @icp-sdk/vetkeys Encrypted Maps client calls them by
those exact names, and the custom metadata methods follow suit for a consistent
interface. Document this in app.mo and the Motoko README, and point to the
upstream Motoko actor mixin (dfinity/vetkeys#405).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…EncryptedMaps macro

Acknowledge the WIP Rust macro ic_vetkeys::export_encrypted_maps_canister!
(dfinity/vetkeys#404) that generates a plain Encrypted Maps canister; this
example hand-writes a custom canister to add the metadata methods on top.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…backend`, drop Makefile

Bump the Rust recipe to @dfinity/rust@v3.3.0 and rename the Cargo package to
`backend` (drops the custom `package:` in the recipe config). Drop
backend/Makefile and add a README "Updating the Candid interface" section using
`icp build backend && candid-extractor … > backend/backend.did`.

Verified: rust deploy + test.sh pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nly CI

The example never had a test.sh on master; drop the ones added during the
split and run deploy-only CI (the deploy verifies build + install). Persistence
is unchanged (flag-based).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
marc0olo added a commit that referenced this pull request Jul 17, 2026
…list, drop web3 jargon

- Motoko README "API level": link to the Motoko password_manager examples
  (../password_manager, ../password_manager_with_metadata) instead of the Rust
  ones (depends on the password_manager split PRs #1446/#1447 being merged).
- security-checklist.md: condense to a focused, language-specific version for
  each of Motoko and Rust (was a 165-line identical copy carried from the older
  device-based encrypted_notes — it wrongly claimed "no inter-canister calls"
  (this version calls the vetKD management canister) and referenced
  submit_ciphertexts / device removal that don't exist here). Link it from each
  README.
- Drop "smart contract" web3 jargon from the backend comments (app.mo, lib.rs):
  "a single canister smart contract" -> "a single canister".

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
marc0olo and others added 2 commits July 17, 2026 12:36
…ty link

Replace "dapp" with "app" in the READMEs and normalize the security
best-practices link to https://docs.internetcomputer.org/guides/security/overview/.
The functional vetKD domain-separator string ("password_manager_example_dapp")
is left unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…toko domain separator

Rename the EncryptedMaps vetKD domain separator "password_manager_example_dapp"
-> "password_manager_example_app" in the Motoko backend. Fresh example, no
previously derived keys to stay compatible with. Backend-only: the frontend
(DefaultEncryptedMapsClient) does not reference the separator.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR completes the vetkeys split series by restructuring password_manager_with_metadata into two self-contained examples (Motoko + Rust), each with its own frontend, build config, and canister naming aligned to backend / frontend.

Changes:

  • Restructures the Rust example into a standalone backend/ workspace + frontend/ build, removing legacy symlink/bindings scripts and renaming the canister to backend.
  • Adds a fully standalone Motoko example directory with its own icp.yaml, mops.toml, and duplicated Svelte frontend wired via @icp-sdk/bindgen.
  • Updates CI workflow triggers/jobs to deploy both language variants from their new locations.

Reviewed changes

Copilot reviewed 63 out of 75 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
rust/vetkeys/password_manager_with_metadata/rust/backend/Makefile Removes legacy Makefile-based build/extract steps from the old nested layout.
rust/vetkeys/password_manager_with_metadata/rust-toolchain.toml Adds a Rust toolchain target declaration for WASM builds.
rust/vetkeys/password_manager_with_metadata/README.md Updates Rust README to standalone layout and new build/deploy instructions.
rust/vetkeys/password_manager_with_metadata/package.json Adds example-root npm workspace scripts for running the frontend from the example root.
rust/vetkeys/password_manager_with_metadata/motoko/mops.toml Removes legacy Motoko mops config from the old hybrid directory.
rust/vetkeys/password_manager_with_metadata/icp.yaml Renames canisters to backend/frontend and updates asset build config for the Rust example.
rust/vetkeys/password_manager_with_metadata/frontend/vite.config.js Switches frontend binding generation to @icp-sdk/bindgen Vite plugin and simplifies dev config.
rust/vetkeys/password_manager_with_metadata/frontend/src/lib/password.ts Repoints type imports to bindgen output paths.
rust/vetkeys/password_manager_with_metadata/frontend/src/lib/password_manager.ts Repoints Candid bindings import and canister env key to PUBLIC_CANISTER_ID:backend.
rust/vetkeys/password_manager_with_metadata/frontend/src/lib/encrypted_maps.ts Updates canister env key and error string to backend.
rust/vetkeys/password_manager_with_metadata/frontend/scripts/gen_bindings.sh Removes the old manual bindings-generation script.
rust/vetkeys/password_manager_with_metadata/frontend/package.json Simplifies frontend package and adds bindgen as a devDependency.
rust/vetkeys/password_manager_with_metadata/frontend/eslint.config.mjs Removes ESLint configuration.
rust/vetkeys/password_manager_with_metadata/frontend/.prettierrc Removes Prettier configuration.
rust/vetkeys/password_manager_with_metadata/frontend/.prettierignore Removes Prettier ignore list.
rust/vetkeys/password_manager_with_metadata/frontend/.gitignore Adds ignores for node_modules, dist, and generated bindings output.
rust/vetkeys/password_manager_with_metadata/Cargo.toml Adds a Rust workspace root with release profile settings.
rust/vetkeys/password_manager_with_metadata/backend/src/lib.rs Introduces the standalone Rust canister implementation with metadata-aware methods.
rust/vetkeys/password_manager_with_metadata/backend/Cargo.toml Renames the Rust canister package to backend.
rust/vetkeys/password_manager_with_metadata/backend/backend.did Adds/commits the Rust backend Candid interface in the new layout.
motoko/vetkeys/password_manager_with_metadata/README.md Adds a Motoko-specific README with standalone deploy instructions.
motoko/vetkeys/password_manager_with_metadata/package.json Adds example-root npm workspace scripts for running the Motoko frontend from the example root.
motoko/vetkeys/password_manager_with_metadata/mops.toml Adds Motoko toolchain/deps and config for a backend canister entrypoint + committed .did.
motoko/vetkeys/password_manager_with_metadata/icp.yaml Adds Motoko example backend/frontend canister definitions and frontend build steps.
motoko/vetkeys/password_manager_with_metadata/frontend/vite.config.js Adds Vite config with @icp-sdk/bindgen and local-dev cookie injection.
motoko/vetkeys/password_manager_with_metadata/frontend/tsconfig.json Adds TS config for the Motoko frontend.
motoko/vetkeys/password_manager_with_metadata/frontend/tailwind.config.mjs Adds Tailwind/DaisyUI config for the Motoko frontend.
motoko/vetkeys/password_manager_with_metadata/frontend/svelte.config.js Adds Svelte preprocessing config.
motoko/vetkeys/password_manager_with_metadata/frontend/src/vite-env.d.ts Adds Vite/Svelte type references.
motoko/vetkeys/password_manager_with_metadata/frontend/src/store/vaults.ts Adds vault/password polling + actions store for the Motoko frontend.
motoko/vetkeys/password_manager_with_metadata/frontend/src/store/notifications.ts Adds notification store helpers.
motoko/vetkeys/password_manager_with_metadata/frontend/src/store/draft.ts Adds localStorage-backed draft persistence store.
motoko/vetkeys/password_manager_with_metadata/frontend/src/store/auth.ts Adds Internet Identity auth wiring and session timeout handling.
motoko/vetkeys/password_manager_with_metadata/frontend/src/main.ts Adds SPA entrypoint wiring.
motoko/vetkeys/password_manager_with_metadata/frontend/src/lib/vault.ts Adds vault model utilities.
motoko/vetkeys/password_manager_with_metadata/frontend/src/lib/sleep.ts Adds a small sleep helper.
motoko/vetkeys/password_manager_with_metadata/frontend/src/lib/password.ts Adds password model utilities using generated Candid types.
motoko/vetkeys/password_manager_with_metadata/frontend/src/lib/password_manager.ts Adds the frontend canister actor + Encrypted Maps client wrapper.
motoko/vetkeys/password_manager_with_metadata/frontend/src/lib/init.ts Adds an (currently empty) init module placeholder.
motoko/vetkeys/password_manager_with_metadata/frontend/src/lib/encrypted_maps.ts Adds Encrypted Maps client construction using PUBLIC_CANISTER_ID:backend.
motoko/vetkeys/password_manager_with_metadata/frontend/src/components/Vaults.svelte Adds vault list view.
motoko/vetkeys/password_manager_with_metadata/frontend/src/components/Vault.svelte Adds single-vault view and navigation.
motoko/vetkeys/password_manager_with_metadata/frontend/src/components/Spinner.svelte Adds a spinner component.
motoko/vetkeys/password_manager_with_metadata/frontend/src/components/SidebarLayout.svelte Adds layout shell with navigation and logout.
motoko/vetkeys/password_manager_with_metadata/frontend/src/components/SharingEditor.svelte Adds UI for granting/revoking vault access rights.
motoko/vetkeys/password_manager_with_metadata/frontend/src/components/Passwords.svelte Adds password list view across vaults.
motoko/vetkeys/password_manager_with_metadata/frontend/src/components/PasswordEditor.svelte Adds rich-text password editor wrapper for typewriter-editor.
motoko/vetkeys/password_manager_with_metadata/frontend/src/components/Password.svelte Adds password detail view.
motoko/vetkeys/password_manager_with_metadata/frontend/src/components/Notifications.svelte Adds notification UI.
motoko/vetkeys/password_manager_with_metadata/frontend/src/components/NewPassword.svelte Adds create-new-password flow including tags/url input.
motoko/vetkeys/password_manager_with_metadata/frontend/src/components/LayoutAuthenticated.svelte Adds authenticated router layout.
motoko/vetkeys/password_manager_with_metadata/frontend/src/components/Hero.svelte Adds unauthenticated hero/login view.
motoko/vetkeys/password_manager_with_metadata/frontend/src/components/Header.svelte Adds header component used across views.
motoko/vetkeys/password_manager_with_metadata/frontend/src/components/EditVault.svelte Adds vault edit view shell.
motoko/vetkeys/password_manager_with_metadata/frontend/src/components/EditPassword.svelte Adds password edit/move/delete UI.
motoko/vetkeys/password_manager_with_metadata/frontend/src/components/DisclaimerCopy.svelte Adds disclaimer copy component.
motoko/vetkeys/password_manager_with_metadata/frontend/src/components/Disclaimer.svelte Adds dismissible disclaimer banner.
motoko/vetkeys/password_manager_with_metadata/frontend/src/assets/svelte.svg Adds Svelte logo asset.
motoko/vetkeys/password_manager_with_metadata/frontend/src/App.svelte Adds root component switching between hero and authenticated layout.
motoko/vetkeys/password_manager_with_metadata/frontend/src/app.css Adds Tailwind directives.
motoko/vetkeys/password_manager_with_metadata/frontend/public/vite.svg Adds Vite logo asset.
motoko/vetkeys/password_manager_with_metadata/frontend/public/.ic-assets.json5 Adds hardened asset-canister header policy configuration.
motoko/vetkeys/password_manager_with_metadata/frontend/package.json Adds Motoko frontend package manifest with bindgen dependency.
motoko/vetkeys/password_manager_with_metadata/frontend/jsconfig.json Adds JS/TS tooling config.
motoko/vetkeys/password_manager_with_metadata/frontend/index.html Adds HTML entrypoint.
motoko/vetkeys/password_manager_with_metadata/frontend/.gitignore Adds ignores for node_modules, dist, and generated bindings output.
motoko/vetkeys/password_manager_with_metadata/backend/backend.did Commits the Motoko backend Candid interface.
motoko/vetkeys/password_manager_with_metadata/backend/app.mo Updates Motoko backend actor class and clarifies snake_case naming rationale.
.github/workflows/vetkeys-password-manager-with-metadata.yml Splits workflow into Motoko + Rust jobs and updates watched paths.
Comments suppressed due to low confidence (1)

rust/vetkeys/password_manager_with_metadata/icp.yaml:6

  • This @dfinity/rust canister configuration omits the package: field. Other Rust examples in this repo consistently specify it (e.g. rust/vetkeys/basic_vetkd/icp.yaml:5-7 uses configuration: { package: backend, candid: ... }). Omitting it may break builds if the recipe can’t infer the Cargo package name.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/vetkeys-password-manager-with-metadata.yml
@marc0olo

Copy link
Copy Markdown
Member Author

Thanks @Copilot. I checked all 11 items against the original shared frontend: every flagged file is byte-identical to the pre-split version. This PR only splits the example into self-contained Motoko/Rust copies (import paths, the PUBLIC_CANISTER_ID:backend env key, vite/bindgen wiring), so none of these were introduced here. To keep the split faithful and avoid re-testing behavior that already works, I'm leaving them untouched — they're best addressed upstream.

Genuine pre-existing bugs worth an upstream fix:

  • SharingEditor.svelte filter with .compareTo(): returns a string (always truthy), so the target user is never removed.
  • SharingEditor.svelte vault lookup (=== + vaultOwnewr typo): compares Principals by reference; can fail for equal values.
  • Password.svelte default metadata: undefined vs required field: typing inconsistency.
  • EditVault.svelte users.find(...) + in: can throw when the current user isn't in vault.users.
  • Passwords.svelte copy ("Filter notes…" / empty-state) references notes instead of passwords.
  • Vault.svelte class string with stray characters: Tailwind classes may not apply.

Minor corrections:

  • vaults.ts uninitialized vaultPollerHandle: harmless; clearInterval(undefined) is a no-op.
  • draft.ts restore checks tags: pre-existing; draft restore is effectively disabled.
  • EditPassword.svelte class ternary: pre-existing and malformed, but it does not fail compilation — Svelte parses {'Read' in accessRights} as a complete interpolation and treats the trailing ? 'hidden' : ''} as literal text. The class renders incorrectly rather than breaking the build (this PR's motoko and rust CI jobs both build the frontend and pass).

CI:

  • No test.sh: intentional. None of these vetKeys examples shipped a test.sh on master, and CI's default identity is anonymous (2vxsx-fae). The workflow deploys both backends from their own working directories (motoko/... and rust/...) in separate jobs — both pass — which verifies build + install + asset sync.

@marc0olo
marc0olo marked this pull request as ready for review July 17, 2026 16:11
@marc0olo
marc0olo requested review from a team as code owners July 17, 2026 16:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants