This is a non-custodial wallet — security is critical. Users trust us with their keys.
Private keys, mnemonics, and passwords must never appear in logs.
Store sensitive data (keys, mnemonics) using SecureStorageService, which uses the device's secure keychain/keystore.
Never trust user input or API responses. Validate before processing.
Environment variables and API keys should be in .env files, not hardcoded.
| Data | Storage | Logging |
|---|---|---|
| Private keys | SecureStorage only | Never |
| Mnemonic seeds | SecureStorage only | Never |
| Passwords/PINs | SecureStorage only | Never |
| Addresses | Any storage | Safe |
| Transaction hashes | Any storage | Safe |
Review dependency updates carefully — supply chain attacks are real. The repo has several layers of automated defense:
pnpm-workspace.yaml sets minimumReleaseAge: 10080 (7 days). Packages
published in the last week are refused at install time. This is our
primary defense against compromised-publish attacks, which are typically
detected and yanked within hours to days. Exceptions live under
minimumReleaseAgeExclude and must be justified in a comment (e.g. a
security patch that we need before the window elapses).
Vulnerable transitives we can't upgrade directly are pinned under
pnpm.overrides in pnpm-workspace.yaml. Use per-major pins (pkg@N: x.y.z)
— range-style overrides like pkg@>=a <b don't actually rewrite pnpm's
resolution when the caller requests a narrower range.
pnpm audit # Fails on any advisory
pnpm audit --prod --audit-level=high # What CI runs to block PRspnpm audit— moderate+ advisories in prod deps block merge.- Lockfile drift check —
pnpm-lock.yamlmust be in sync with everypackage.json. - Gitleaks — scans the PR diff for committed secrets. Local allowlist
lives in
.gitleaks.toml; add a new entry rather than disabling a rule globally. - Pinned actions — every GitHub Action is pinned to a full commit
SHA with a trailing version comment. Don't use floating tags
(
@v4,@main) — Dependabot handles SHA bumps. - Least-privilege permissions —
contents: readis the default; jobs elevate only what they need. Everyactions/checkoutusespersist-credentials: false.
- CodeQL — JS/TS static analysis weekly + on PR; findings go to the Security tab.
- OpenSSF Scorecard — weekly posture score, published to the public Scorecard API.
- SBOM — CycloneDX SBOM generated
on every push to
mainand weekly; 90-day artifact retention. - Dependabot — weekly grouped updates for npm and github-actions. Framework-tier majors (React, React Native, Expo, TypeScript, ESLint) are ignored and bumped manually.
Gitleaks runs locally against the commits you're about to push. It
soft-skips if gitleaks isn't installed — brew install gitleaks
enables it. The authoritative scan is still the CI job.
If you're unsure whether something is secure, ask. Security mistakes are expensive.