Kei Wallet is the standalone, non-custodial exit door for assets earned in Kei games. It signs locally in the browser: private keys and seeds are never sent to a node or backend.
This repository is a GitHub fork of BananoVault, which is itself a fork of NanoVault. The current wallet surface is a small TypeScript application using the merged kei-transaction SDK; the original Angular application remains in legacy-bananovault/ for provenance and reference. See THIRD_PARTY_NOTICES.md.
The plan to make this the canonical hosted wallet at wallet.keicoin.org — history, estimated value, a phone-installable PWA, and the game-login browser extension — is specified in docs/canonical-wallet/, with milestones in MILESTONES.yaml and the rollout in MIGRATION.md.
- Connects to the public Kei testnet by default. Testnet Kei has no value and the chain may reset.
- Supports an explicit offline mock network and a user-supplied testnet node URL.
- Shows the account address, Kei balance, token balances, item inventory, and claim bundles held by the wallet.
- Imports claim bundles and provides claim-all.
- Imports and persists a seed locally through the SDK seed store. No custodian or recovery service exists.
- Implements
on-request,never, and testing-onlyalwaysseed reveal policies, plus global streamer mode. - Blocks an outbound
fetchbefore transport if its URL, headers, or body contain a seed known to the wallet. - Shows this wallet's own open offers and settled trades, and cancels an offer to release what it locked.
It shows your offers and your settled trades, read from this wallet's own chain through kei.market.mine() and kei.market.trades(). It does not show the network's order book, and no wallet can: an offer lives on the chain of whoever wrote it (SPEC §9.1), and Kei deliberately ships no indexer to gather them (§9.4), so listing every offer would mean already knowing every account. A wallet can only report chains it knows.
The empty state is worded to keep that distinction, because "no offers exist" and "this wallet never asked" look identical to a player and only one of them is something this wallet can actually establish.
Two things the panel is careful about, both of which are easy to get backwards:
- An expired offer is still acceptable. Expiry is advisory and the ledger never enforces it (SPEC §9.3), so the panel marks an expired offer as still acceptable rather than implying it is safe. Cancelling is what actually releases the lock.
- A trade's
mineflag does not mean you sold it. It is true whenever this wallet was either party, so the seller is identified by comparingselleragainst the wallet's address.
The app uses kei-transaction; it does not implement key derivation or signing itself. A seed is generated or imported client-side and kept in browser storage. Browser storage is not durable, so back up any wallet that holds value.
Seed reveal follows SPEC §6.6:
on-requestrequires a plain-language risk confirmation, renders the seed only after that request, keeps it blurred, and makes it legible only while pressed.neverdoes not read or render the seed.alwaysis conspicuously marked for local testing only.- Streamer mode overrides every policy and immediately removes any seed-bearing DOM node.
- There is no copy button, telemetry, analytics, or crash reporter.
- Arbitrary error text is never echoed into the UI.
The transport guard is defense in depth. The underlying SDK still bears the primary responsibility to submit public signed blocks rather than secrets.
Requirements: Node.js 22.12 or newer and the published kei-transaction 0.8 packages.
npm ci
npm test
npm run buildnpm test typechecks before it runs vitest. Vitest transpiles rather than
typechecks, so without that step a type error in src/ passes the suite and
only shows up in npm run build.
Run npm run dev for the local Vite server. Unit tests use fakes and jsdom; they do not contact a network.
This is an M6 development slice, not a mainnet wallet. Mainnet is not open. Testnet balances can disappear, the network can be unavailable, and claim discovery is not global: a game must hand the wallet the proof for an entitlement before it can be listed or claimed.
New Kei Wallet work is MIT-licensed under LICENSE. Upstream licensing evidence and attribution are recorded separately because the upstream repositories omit standalone license texts.