Rust + Dart tooling for the Solana Seeker secure element (Seed Vault).
The Solana Seeker (and Saga) store seeds in a hardware secure element that is
only reachable through Android's Seed Vault system component. There is no
raw APDU/native interface: third-party apps talk to the Seed Vault Wallet
Contract V1: a read-only ContentProvider
(com.solanamobile.seedvault.wallet.v1.walletprovider) plus seven
startActivityForResult intent actions: usually via Solana Mobile's official
com.solanamobile:seedvault-wallet-sdk Java/Kotlin library. Secrets never
leave the vault; apps receive public keys, opaque auth tokens, and signatures.
This monorepo follows the same layout as the sibling hardware repos
(sound, microphone, bluetooth, camera, airdrop):
| Path | Contents |
|---|---|
native/seed_vault_core |
Rust crate: contract types, BIP32/BIP44 path URIs, SLIP-0010 derivation oracle, availability model, C ABI (JSON payloads) for Dart FFI, feature-gated Android JNI adapter |
native/seed_vault_cli |
Thin CLI over the core crate for host-side exercising |
packages/seeker_dart |
Pure Dart package (dart:ffi, pluggable backend registry, unsupported floor): no Flutter needed |
packages/seeker |
Flutter ffiPlugin (cargokit builds seed_vault_core per-ABI); thin re-export + ensureInitialized(); Android manifest carries <queries> + ACCESS_SEED_VAULT |
packages/seeker/example |
Demo app: availability status on button press |
vendor/seed-vault-sdk |
Pinned submodule of solana-mobile/seed-vault-sdk @ v0.4.0 (Apache-2.0): the authoritative contract reference |
spikes/ |
Quarantined experiments (kept out of native/ and packages/) |
docs/ |
Research notes, vendoring provenance, host status |
The Flutter plugin never talks to Rust directly: it only bundles builds of
the native library (cargokit, per-ABI). All FFI lives in the pure-Dart
package, so CLI/server use needs no Flutter: Rust seed_vault_core exposes a
JSON-over-C-ABI (sv_* functions + sv_last_error), and seeker_dart
binds it with hand-written typedefs, falling back to an unsupported backend
where the library can't load.
Root pubspec.yaml is a pub workspace with melos-in-pubspec scripts:
dart run melos run analyze / test / format / native:build /
native:test / native:cli.
Rust tooling, the Dart/Flutter packages, and the instrumented test
suite are validated on the emulator and on real Seeker hardware. See
docs/RESEARCH.md for findings and docs/HOST_STATUS.md for the
toolchain setup.
- Detection is two-axis: implementation (Secure / Simulated / Unavailable
/ Unsupported) x access (None / Standard / Privileged / Unsupported).
Probe strict
SeedVault.isAvailable(ctx)first, then permissiveisAvailable(ctx, true)to distinguish simulator from real hardware.Unsupported= the platform has no Seed Vault concept at all (what host builds report);Unavailable= no vault installed/accessible. - Third-party wallets get standard access (runtime permission
ACCESS_SEED_VAULT); privileged access is signature-only, for system apps. - Signing and key derivation happen inside the vault; the Rust-side SLIP-0010/ed25519 code here is a test oracle (to cross-check the real SDK), not a production signing path.
- Anything needing an Android
Context/Activity(permission prompt,startActivityForResulthandoff) lives in a thin Kotlin/plugin layer; Rust owns types, paths, serialization, and the C ABI.