EVE Vault Wallet is a Chrome and Firefox MV3 extension and web app built with WXT and React. It implements the Sui Wallet Standard to let dApps discover and connect to a user wallet. User authentication supports EVE Frontier FusionAuth via the browser's identity API. After login, a Sui zkLogin address is derived and exposed to dApps via the wallet standard.
- EVE Frontier OAuth (FusionAuth) with PKCE
- zkLogin address derivation
- Wallet Standard implementation for dApp discovery (Chrome & Firefox)
- PIN-protected vault — Argon2id (memory-hard) key derivation; decrypted keys held only in offscreen/in-process memory, never persisted
- Auto-lock 10 minutes after unlock (web + extension), with a PIN re-entry screen if the vault expires mid-approval
- Transaction simulation in the approval popup — projected balance changes, gas, object changes, events, and success/failure before signing
- Automatic zkLogin session recovery on epoch expiry (rotates keys, retries; address unchanged)
- Multi-network support (Mainnet, Devnet, Testnet, Localnet)
- Multi-tenant FusionAuth configuration
- Reports build version, commit, and platform to dApps via the wallet standard
- Strict Content-Security-Policy on extension and web surfaces
- Transaction signing with zkLogin and private key (localnet-only)
- Zustand for client state
- Browser storage persistence (extension)
EVE Vault uses zkLogin to create a Sui wallet address from your OAuth credentials (FusionAuth). Your wallet address is cryptographically derived from your authenticated identity using zero-knowledge proofs.
On Sui Localnet, signing uses a local Ed25519 keypair (imported in the app), which keeps dev/test flows simple.
After signing in, you set a PIN. The PIN runs through Argon2id to unlock an ephemeral signing key that lives only in memory (the extension's offscreen keeper, or the web app's tab) and is never written to storage. The vault auto-locks 10 minutes after unlocking; if it locks while a signing approval is open, you're prompted to re-enter your PIN before the transaction can be signed.
For detailed technical information, see the Architecture Documentation and Sui zkLogin docs.
Latest release (Chrome & Firefox):
https://github.com/evefrontier/evevault/releases
Latest extension ZIPs (CI, stable filenames):
- Chrome: releases/latest/download/eve-vault-chrome.zip
- Firefox: releases/latest/download/eve-vault-firefox.zip
See docs/RELEASE_EXTENSION.md.
Web app:
https://evevault.evefrontier.com/
- Node.js (see
.nvmrc, currently 25.x) - Bun (package manager used in this repo; pinned via
packageManagerinpackage.json) - FusionAuth public OAuth application with PKCE enabled
bun install
Create a .env at the repository root (WXT loads env from the monorepo root). OAuth client IDs and tenant URLs are configured in packages/shared/src/utils/constants.ts.
# Extension (when required by your build / OAuth redirect)
EXTENSION_ID=
- FusionAuth admin → Applications → your app → OAuth
- Add redirect URI:
https://<your-extension-id>.chromiumapp.org/(extension flow) - Configure the application as a public OAuth client using authorization code + PKCE
- Enable scopes:
openid,profile,email
# Extension only (Chrome)
bun run dev:ext
# Extension only (Firefox)
bun run dev:ext:firefox
# All apps — both browsers + web
bun run dev
# All apps — Chrome + web only
bun run dev:chrome
# Web only
bun run dev:web
Chrome
- Open
chrome://extensions - Enable Developer mode
- Load unpacked → select
apps/extension/.output/chrome-mv3(afterdevorbuildhas produced output)
Firefox
- Open
about:debugging#/runtime/this-firefox - Load Temporary Add-on… → pick any file inside
apps/extension/.output/firefox-mv3
- Open the extension popup
- Sign in with your configured tenant
- After success, you should see your zkLogin address and balance (when the network and APIs are available)
- Use the in-app network selector to switch networks where supported
# Extension (Turborepo) — builds both Chrome and Firefox
bun run build:ext
# Web app
bun run build:web
# Both apps
bun run build
# Chrome web-store build / zip
bun run build:ext:webstore
bun run zip:ext:webstore
Extension artifact directories: apps/extension/.output/chrome-mv3/ and apps/extension/.output/firefox-mv3/
Biome is used for format + lint.
bun run lint
bun run lint:fix
bun run typecheck
Run a task for one workspace, for example:
bunx turbo run lint --filter=@evevault/web
Staged *.{ts,tsx,js,jsx,json,css} files are run through biome check --write before commit (see root package.json lint-staged).
Config: biome.json, .biomeignore, .husky/pre-commit.
bun run test
bun run test:run
bunx turbo run test --filter=@evevault/shared
Monorepo: Bun workspaces + Turborepo.
evevault/
├── packages/
│ └── shared/ # Shared types, auth, wallet, UI used by web + extension
└── apps/
├── extension/ # WXT Chrome MV3 extension
└── web/ # Vite + React web app
- Release extension (CI) — GitHub Actions ZIP
- ADR: hybrid monorepo structure
- Troubleshooting
- Architecture (zkLogin / auth) — external ADR
EVE Vault registers as Eve Vault through the Sui Wallet Standard. Use any stack that lists Wallet Standard wallets (for example @mysten/dapp-kit); connect or filter for the wallet named Eve Vault. The extension injects the provider in pages where it is allowed to run.
Alongside the standard Sui features (connect, disconnect, sign personal message, sign transaction, sign-and-execute), EVE Vault exposes two EVE-specific features: evefrontier:vaultVersion (reports the build's vaultVersion, short commit, and platform so dApps can detect outdated installs and tell which client is connected) and a sponsored-transaction feature.
Verifying a sign-in server-side:
signPersonalMessagereturns{ bytes, signature }. Verify the signature against a message your server rebuilds from a nonce it issued — never against thebytesthe wallet returned, which are attacker-controlled and let any previously signed message be replayed. EVE Vault addresses are zkLogin, so pass aclientto the verifier. See Verifying a Sign-In Server-Side for a full example.
- Open the popup from the toolbar icon
- Complete sign-in for your tenant
- Once authenticated, the wallet is available to permitted sites
- Switch Sui networks from the network selector when offered
- zkLogin maxEpoch expiry is recovered automatically: on an expired-proof error the wallet rotates the ephemeral key and retries once (the zkLogin address is unchanged), so re-signing is largely transparent
- Use Quick start and Build above for a working tree
- Read ADR: hybrid monorepo structure for layout decisions
- See Troubleshooting for common extension and env issues
- WXT and React
- Sui Wallet Standard: @mysten/wallet-standard
- zkLogin: @mysten/sui
- Zustand
- oidc-client-ts + FusionAuth