Skip to content
starknet-innovationPublic

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

122 Commits

Folders and files

Repository files navigation

strkd — Starknet Wallet Companion

A desktop menu-bar companion wallet for Starknet. It stores a seed safely, derives multiple accounts from it, and exposes a local service that other programs on the same machine — AI agents, desktop apps — can call to request wallet operations. The wallet never returns private keys; it returns signed payloads (and can broadcast on request). Every signing or state-changing request pops a menu-bar confirmation, and all requests are logged.

It speaks the standard Starknet wallet_rpc.json API plus a small companion_* extension namespace, and delegates cryptography to krusty-kms.

It also bundles an on-device proving companion (the prover crate, merged from dinner): hand it an already-signed payload via companion_prove and it generates a SNIP-36 proof locally — the secret never leaves the machine. companion_signAndProve goes one step further, signing the private virtual transaction and proving it in a single call. The prover holds no keys and sits strictly downstream of signing.

⚠️ Experimental. Not for real funds. krusty-kms is flagged experimental by its authors and the crypto path is unaudited. Use throwaway test seeds only — never a real mnemonic or a seed controlling funds. See the security notes in the spec §14.

Status

All three layers are built. The crypto core (wallet-core) and the loopback service (wallet-rpc) are green — 92 tests, clippy clean — covering derivation, signing, the vault, the full wallet_* + companion_* handlers, auth, the approval broker, permission grants, and the request log. The Tauri menu-bar app (desktop/) compiles and its frontend builds, but the GUI is not yet run-verified (tray, dialogs, notifications, auto-lock, Dock icon need a human launch). Broadcasting + fee estimation work against a node configured in the Settings tab; Sepolia reads/estimates are live-verified, while the broadcast hop still needs a funded-account submit.

The prover crate is built and tested (the success path via a test-only stub Prover, since there is no mock backend — both real backends fail honestly when unconfigured), with companion_prove* covered end-to-end in the wallet-rpc dispatch tests. The native SNIP-36 backend is live-verified on Sepolia (2026-07-02, prover pin v1.2.2): it generated a proof-carrying invoke on-device that verified on-chain. Next up: bramble convergence — see docs/project/bramble-convergence.md. Privacy (strk20*) is parked, not pending.

For the authoritative, always-current state, see docs/project/status.md.

Build & test

The headless core (wallet-core + wallet-rpc):

cargo build
cargo test                  # core + service test suite
cargo clippy --all-targets  # lint

The desktop menu-bar app (Tauri 2 + React + TypeScript + Vite), under desktop/:

cd desktop
npm install
npm run tauri dev           # dev (hot reload; child processes — for development)
npm run tauri build         # build an installable bundle (recommended for use)
#   → src-tauri/target/release/bundle/macos/strkd.app  (drag to /Applications)

Install the built strkd.app and launch it like any app — it shows in the Dock and lives in the menu bar (the tray); closing the window only hides it, and clicking the Dock icon re-shows it. Quit cleanly via the tray → Quit. Set the Starknet RPC endpoint in the app's Settings tab to enable broadcasting + fee estimation.

Requires a Rust toolchain (+ Node for the desktop app). The first core build fetches krusty-kms from git (pinned commit), so it needs network access. The desktop crate is its own Cargo crate, excluded from the root workspace, and reuses the core crates by path.

The headless core is covered by automated tests. The desktop GUI is built but not run-verified — confirming the tray/onboarding/approval flows means running the app on a machine with a display.

The strkd CLI

strkd (crate strkd, under crates/wallet-cli/) is a thin command-line client for the running menu-bar app. It holds no keys — it discovers the app's loopback service via port.lock, pairs once, and speaks the same wallet_* / companion_* API that agents use. Signing and approvals still happen in the app.

strkd pair --name my-cli   # one-time; approve the prompt in the menu bar
strkd status               # lock state, network, grant
strkd accounts             # accounts this client may use
strkd usage                # the wallet's self-describing API doc
strkd sign  --account 0x… --data @typed_data.json
strkd send  --account 0x… --to 0x… --function transfer --calldata 0x…,0x…
strkd send  … --submit     # broadcast (IRREVERSIBLE); default is sign-only

Add --json for a clean machine contract (only JSON on stdout; errors as {"error": …} on stderr) and -q/--quiet to drop progress text — both work before or after the subcommand, so strkd accounts --json | jq pipes cleanly.

Install

From this repo (needs a Rust toolchain):

cargo install --path crates/wallet-cli   # installs the `strkd` binary

Prebuilt binaries are distributed with cargo-dist. Once a release is cut, end users install without a toolchain via the shell installer, or by downloading a tarball from the release page:

curl -LsSf https://github.com/starknet-innovation/strkd/releases/latest/download/strkd-installer.sh | sh

It installs to ~/.cargo/bin. Per-target archives (strkd-aarch64-apple-darwin.tar.xz and friends, for Apple silicon + Intel macOS and x86_64 + arm64 Linux) are attached to the same release, each with a .sha256, plus a signed build provenance attestation. To verify a download before running it:

gh attestation verify strkd-aarch64-apple-darwin.tar.xz -R starknet-innovation/strkd

Homebrew is not wired up yet: it needs the starknet-innovation/homebrew-tap repo to exist and a HOMEBREW_TAP_TOKEN secret. The root Cargo.toml dist block documents exactly what to re-add.

Releases

Two independent tracks, each triggered by its own tag shape, each publishing a draft GitHub Release for a human to review and publish:

Tag Workflow Ships
v0.3.1 release.yml (generated by dist) strkd CLI: shell installer + per-target tarballs + checksums
desktop-v0.3.1 desktop-release.yml Menu-bar app with the prover bundled: .dmg, .app.tar.gz, .deb, .rpm, .AppImage
git tag v0.3.1         && git push origin v0.3.1          # CLI
git tag desktop-v0.3.1 && git push origin desktop-v0.3.1  # desktop app

The desktop build stages the pinned prover from prebuilt release artifacts (desktop/scripts/prover-pin.env is the single source of truth for the version) and gates on snip36 doctor before building the app, so a broken proving stack fails the release rather than shipping. Every staged prover file is also checked against SHA-256 hashes pinned in that file, independent of the prover release's own checksums.

What every release guarantees:

  • Drafts only. Nothing is public until a maintainer publishes it, and releases/latest/download/… keeps serving the previous published release until then.
  • Verifiable downloads. Checksums (CLI: per-file .sha256 + sha256.sum; desktop: SHA256SUMS) and a signed provenance attestation for every file.
  • Pinned toolchain. Every GitHub Action is pinned to a commit SHA, and cargo-dist is installed from a hash-pinned tarball, never curl | sh.
  • Reproducible dependencies. Cargo.lock (root and desktop/src-tauri) is committed, and CI and both release workflows fail on a stale lockfile.
  • Least privilege. Workflow tokens are read-only except in the one job that creates the release. Manual desktop releases run from main only.
  • Unsigned desktop apps, and the release notes say so. The .dmg/.app are not code-signed or notarized yet: macOS users must right-click → Open, and should verify the download first.

Before publishing a draft, check the attached files and notes, then press Publish on the release page.

Publishing: only the CLI release may be "Latest". GitHub marks one release per repo as Latest, by default the one published most recently. The CLI install command fetches releases/latest/download/strkd-installer.sh, which exists only in the CLI release. If a desktop release becomes Latest, that command breaks for everyone. So publish the desktop release with Set as the latest release unticked, and the CLI release with it ticked:

gh release edit desktop-vX.Y.Z --draft=false --latest=false   # desktop: never Latest
gh release edit vX.Y.Z         --draft=false --latest         # CLI: Latest
curl -sI https://github.com/starknet-innovation/strkd/releases/latest | grep -i location
                                                              # must end in /tag/vX.Y.Z

Maintainers. CLI dist policy lives in [workspace.metadata.dist] (root Cargo.toml). release.yml was generated from it and carries one deliberate local edits, listed in its banner: the release-safety changes above, and a narrowed tag glob, so desktop-v* tags don't trigger the CLI release. Because allow-dirty = ["ci"] is set, dist generate leaves that file alone rather than reverting the edit, which also means upstream dist CI changes are not picked up automatically; the banner at the top of the workflow explains how to resync deliberately.

cargo install cargo-dist   # provides the `dist` binary
dist plan --tag v0.3.1     # dry run: exactly what a release would contain
dist build --artifacts=local --target aarch64-apple-darwin --tag v0.3.1
                           # build the real artifacts for one target, locally

While strkd is alpha (test seeds only), prefer cargo install for internal dogfooding and keep the public channels quiet.


Documentation

All documentation is indexed in docs/index.md — that is the single entry point; start there if you're unsure where to look. The docs are organized into three areas by the question they answer:

Area Location Answers Start with
Design spec/ Why and what we're building spec/wallet-companion-spec.md
Code docs/code/ How the implementation works docs/code/architecture.md (then wallet-core.md, wallet-rpc.md, desktop.md)
Project docs/project/ Where we are and how we work docs/project/status.md

How to find what you need

Project management

How development is tracked and handed off — what's been done, what remains, how to log progress, and how to pick up where the last session stopped — is governed by docs/project/workflow.md. Read it before doing project work; it is prescriptive. In short:


Contributing to the documentation

Keep docs navigable by following these rules. They are not optional — drift here makes the whole tree untrustworthy.

  1. Three homes, by purpose. Design → spec/. Code → docs/code/. Project management → docs/project/. Put a doc where its question belongs, not where it's convenient.
  2. One topic per file; one fact in one place. Don't restate the spec in a code doc or vice versa — link to the source of truth. Duplication is the main thing we're preventing.
  3. Index everything. Every doc file must be listed in docs/index.md. Adding a doc without indexing it is an incomplete change. When you add a whole new area, add a row to the Documentation table above too.
  4. One crate → one reference. When a new crate is built, add docs/code/<crate>.md and link it from docs/code/architecture.md and the index.
  5. Naming & links. Files are kebab-case.md. Use relative links between docs so they work on disk and in any viewer. Use absolute YYYY-MM-DD dates.
  6. Docs ship with the change. Code changes update the relevant code doc in the same change; project state changes update status.md and append to progress-log.md (per workflow.md).
  7. Don't break the boundary in prose. When documenting anything that touches keys, reinforce the security boundary; never include real seed/key material in an example.

If you're unsure where something goes, it almost always belongs in exactly one of the three areas above — pick by the question it answers, then link it from the index.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages