Securely manage your CSPR tokens, interact with dapps and sign transactions with Casper Wallet, the Go-To self-custody wallet for the Casper blockchain.
The recommended way of integrating Casper Wallet into your app is through CSPR.click, which provides a combined integration of major wallets in the Casper ecosystem, all at once, without the burden of maintaining multiple integrations at the same time. Please head over to the CSPR.click documentation to start.
Casper Wallet Playground is a React webapp created as a developer tool to help test integration with various features available in Casper Wallet.
Open https://github.com/make-software/casper-wallet-playground
Clone this repository and run following commands from the repo root folder. NOTE: Node.js LTS is required.
npm install
npm run startThis will open webapp automatically in a new tab.
- Navigate
chrome://extensions/in Chrome browser - Enable
Developer mode(right top corner, at least for Chrome 98) - Click on
Load unpackedbutton (left top corner) - Pick
build/chromefolder frombuilds.zipdeliverable orbuildsfolder when building from sources.
To open as a tab:
- Open a new tab and use the link
chrome-extension://{paste ID here}/popup.html
- Navigate
about:debugging#/runtime/this-firefoxin Firefox browser - Click on
Load Temporary Add-on...button. - Pick
build/firefox/manifest.jsonfile frombuilds.zipdeliverable orbuildsfolder when building from sources.
To open as a tab:
- Open new tab and fill the link
moz-extension://{paste Internal UUID here}/popup.html
The Safari build is distributed through TestFlight — install it from there, then follow steps 3-4 below.
To run it from sources instead:
- Run
npm run build:safarito produce the web-extension resources inbuild/safari. - Open
xcode-project/Casper Wallet/Casper Wallet.xcodeprojand run the "Casper Wallet" scheme. - Follow instructions and enable Casper Wallet in opened Extensions Preferences window.
- Open Safari and enable unsigned extensions. Extension should be available.
For more information please follow the link
Working on any macOS or Linux machine with Node.js 22 and npm 10+ installed (see .nvmrc for the exact version). If you use nvm, run nvm use from the repo root to pick up the right version.
Clone this repository and run the following command from the repo root folder.
npm run setupnpm lifecycle scripts are disabled by default (.npmrc sets ignore-scripts=true)
as a supply-chain safeguard, so a plain npm install runs no dependency
install scripts and does not set up the git hooks. npm run setup performs a
full install: npm ci, then runs the approved install scripts via
@lavamoat/allow-scripts, then installs the git hooks.
Approved dependency install scripts live in the lavamoat.allowScripts allowlist
in package.json. To add a dependency that ships an install script, run
npx allow-scripts auto, then review the diff and set the new entry to true
only if the script is trusted and required — otherwise leave it false. CI fails
on any install script that is not explicitly configured.
chmod +x scripts/*Chrome:
npm run start:chromeFirefox:
npm run start:firefoxYou can run both of these commands in parallel. Safari has no watch mode —
build it with npm run build:safari and run the app from Xcode.
Chrome:
npm run build:chromeFirefox:
npm run build:firefoxSafari (web-extension resources only — see below):
npm run build:safariAll at once:
npm run build:allFor Safari both commands stop at the web-extension resources in build/safari.
The app around them lives in xcode-project/Casper Wallet and is built by
npm run release:safari (see below), which reads those resources from
build/safari directly — they are not part of the archive below.
build:all bundles the Chrome and Firefox builds into
build/casper-wallet-<version>rc<n>#<sha>.zip, taking <version> from
package.json. The rc number restarts at 1 whenever that version changes and
otherwise continues from the highest archive already sitting in build/ — so
keep the previous archives there if you want the count to carry on.
Alongside it come build/casper-wallet-chrome-<version>rc<n>#<sha>.zip and its
firefox counterpart, ready to upload to the stores as they are: each holds
the extension at the zip root, which is what the stores expect.
npm run release:safari takes the Safari extension the whole way: it rebuilds
build/safari, stamps the version into the Xcode project, archives the app and
uploads it to App Store Connect. It needs macOS with Xcode and an App Store
Connect API key, described by a gitignored .env.release in the repo root:
ASC_KEY_PATH=AuthKey_XXXXXXXXXX.p8
ASC_KEY_ID=XXXXXXXXXX
ASC_ISSUER_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
ASC_TEAM_ID=XXXXXXXXXXKeep these out of .env, which npm run build:src copies into the source-review
package — the script refuses to run if it finds ASC_ values there. Exported
variables win over the file. ASC_KEY_PATH is resolved against the repo root and
.p8 files are excluded from that package, so the key may sit next to it under
its Apple-issued name.
MARKETING_VERSION comes from package.json, so the app version is bumped by
editing package.json and nothing else. CURRENT_PROJECT_VERSION is incremented
on every upload, because App Store Connect rejects a build number it has already
seen; the script prints the git commit that records it in
Casper Wallet.xcodeproj/project.pbxproj. A run that ships nothing — a failure,
or --no-upload — restores it instead. SAFARI_BUILD=<n> overrides it for one
run.
Signing is left to Xcode's automatic mode, which needs a Mac Installer
Distribution certificate in the login keychain to sign the .pkg. An API key
with the App Manager or Admin role mints one on demand; otherwise create it once
in the Apple Developer portal. To exercise all of that without sending a build:
npm run release:safari -- --no-uploadnpm run build:src produces build/casper-wallet-src#<sha>.zip, the package
submitted alongside the extension for source review. Rebuilding it yields an
artifact byte-identical to the published one — including manifest.json:
unzip casper-wallet-src#<sha>.zip -d casper-wallet-src
cd casper-wallet-src
npm ci
npm run build:firefox # or build:chrome / build:safariThe package carries no .git, so the HASH=$(git rev-parse HEAD) in the build
scripts resolves to nothing there. The commit stamped into
manifest.version_name comes from build-hash.json, written into the package by
npm run build:src. To build a tree that has neither — a downloaded tarball, for
instance — pass the commit explicitly:
HASH=<full commit sha> npm run build:manifest:v2:firefoxA production build with no commit available anywhere fails rather than stamping a placeholder, since the resulting artifact could not be reproduced.
Unit tests are written with Jest and colocated with the source code.
npm testTo collect coverage (CI enforces a coverage gate):
npm run test:coverageRun the same checks as CI (Prettier, ESLint, TypeScript, knip and unit tests with coverage) with a single command:
npm run ci-checkThe individual checks are also available as separate scripts: npm run format:check, npm run lint, npm run tsc, npm run knip.
To run the project's Semgrep static-analysis rules locally (requires the semgrep CLI):
npm run semgrepWrite tests into the e2e-tests folder. Each script below builds the extension first and then runs the Playwright suite.
In UI mode:
npm run e2e:chrome:ui:popup
npm run e2e:chrome:ui:onboardingHeadless:
npm run e2e:chrome:headless:popup
npm run e2e:chrome:headless:onboarding
npm run e2e:firefox:headless:smoke- Contributions are welcome — see CONTRIBUTING.md.
- To report a security vulnerability, please follow SECURITY.md — do not open a public issue.
Casper Wallet is licensed under the Apache License 2.0.
