mirror of
https://github.com/luxfi/wallet.git
synced 2026-07-27 03:37:41 +00:00
wallet: scrub Avalabs IP brand refs
This commit is contained in:
@@ -45,7 +45,7 @@ pin a stable `UPSTREAM_REF` against `luxfi/wallet@<sha>` instead of forking.
|
||||
| `components/` (BigNumInput, CopyText, QrInput, QrReader Vue) | `@hanzo/gui` v7 (aliased to `apps/web/src/lib/gui-stub.tsx`) | DROP — primitives covered, Vue forbidden |
|
||||
| `sdk/` standalone (Asset/Csv/Explorer/History/Keystore/Network/UniversalTx/Wallet) — published as `@luxfi/wallet-sdk@0.20.29` on npm | `@l.x/api@1.0.8` (canonical SDK surface) + the same `@luxfi/wallet-sdk` already on npm | DROP — SDK already published; canonical apps consume `@l.x/api` |
|
||||
| `app/src/locales/*.json` (31 languages, 740-line en.json keyed against legacy Vue UI) | `pkgs/wallet/src/features/i18n/deviceLocaleWatcherSaga.ts` (locale detection only) | DROP — keys target Vue1-era UI labels; no overlap with canonical screen text. Re-translation belongs to a fresh i18n pass against current strings, not a migration of stale ones |
|
||||
| `app/src/ERC20Tokenlist.json`, `ERC721Tokenlist.json` | `pkgs/chains/` + token registries from `@l.x/api` | DROP — wwallet lists target chainId 43114 (Avalanche) which is wrong product surface for the Lux wallet |
|
||||
| `app/src/ERC20Tokenlist.json`, `ERC721Tokenlist.json` | `pkgs/chains/` + token registries from `@l.x/api` | DROP — wwallet lists target chainId 43114 (legacy upstream chain) which is wrong product surface for the Lux wallet |
|
||||
| `app/src/components/wallet/{studio,advanced/{SignMessage,VerifyMessage},earn/StakingCalculator,portfolio/Collectibles}` | Not in canonical web v0.1 (per SCREENS.md spec freeze 2025-12-15) | DROP — these features are out of scope for the new wallet UX. Re-add (if desired) belongs to a fresh design pass against `@hanzo/gui` v7 primitives, not a Vue→React translation of stale code |
|
||||
| Cypress E2E suite (`app/cypress/`) | Canonical uses Playwright in `apps/extension/e2e/` and Maestro on mobile | DROP — wrong test runner for the canonical bones |
|
||||
| Static brand strings (Lux-only, hardcoded RPC URLs) | `@luxfi/wallet-brand` runtime brand.json + ConfigMap overlay | DROP — superseded by white-label runtime config |
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* PIN re-authentication contract.
|
||||
*
|
||||
* Foundation Blue's auth slice owns the actual PIN storage (Argon2id KDF +
|
||||
* encrypted vault, NEVER plaintext). This module exposes the verification
|
||||
* surface every other slice needs:
|
||||
*
|
||||
* verifyPin(pin) — async; resolves true if `pin` decrypts the vault.
|
||||
* changePin(old, new) — async; re-encrypts the vault under the new PIN.
|
||||
* revealMnemonic(pin) — async; returns the decrypted BIP-39 phrase.
|
||||
*
|
||||
* Until Foundation Blue lands the real implementation, this file ships a
|
||||
* deliberate placeholder that throws on call. We refuse to ship a fake
|
||||
* "accepts any PIN" path because it would silently weaken security in dev.
|
||||
*
|
||||
* The contract is what Settings + Signing import; Foundation will replace
|
||||
* the body without touching call sites.
|
||||
*/
|
||||
|
||||
const FOUNDATION_NOT_WIRED =
|
||||
"auth slice not wired — Foundation Blue must implement pin.ts. " +
|
||||
"This is intentional: refusing to ship a permissive stub for security."
|
||||
|
||||
export interface PinAuth {
|
||||
verifyPin(pin: string): Promise<boolean>
|
||||
changePin(oldPin: string, newPin: string): Promise<void>
|
||||
/** Returns the BIP-39 mnemonic. Caller MUST clear the string promptly. */
|
||||
revealMnemonic(pin: string): Promise<string>
|
||||
/** True if biometric unlock is available on this device. */
|
||||
biometricAvailable(): Promise<boolean>
|
||||
}
|
||||
|
||||
/**
|
||||
* Foundation Blue calls `installPinAuth(realImpl)` once at boot to register
|
||||
* the actual implementation. Call sites then use `getPinAuth()`.
|
||||
*/
|
||||
let installed: PinAuth | null = null
|
||||
|
||||
export function installPinAuth(impl: PinAuth): void {
|
||||
installed = impl
|
||||
}
|
||||
|
||||
export function getPinAuth(): PinAuth {
|
||||
if (installed) return installed
|
||||
return {
|
||||
verifyPin: async () => {
|
||||
throw new Error(FOUNDATION_NOT_WIRED)
|
||||
},
|
||||
changePin: async () => {
|
||||
throw new Error(FOUNDATION_NOT_WIRED)
|
||||
},
|
||||
revealMnemonic: async () => {
|
||||
throw new Error(FOUNDATION_NOT_WIRED)
|
||||
},
|
||||
biometricAvailable: async () => false,
|
||||
}
|
||||
}
|
||||
|
||||
/** Constant-time string compare — used for PIN confirm-match check in UI. */
|
||||
export function constantTimeEqual(a: string, b: string): boolean {
|
||||
if (a.length !== b.length) return false
|
||||
let diff = 0
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
diff |= a.charCodeAt(i) ^ b.charCodeAt(i)
|
||||
}
|
||||
return diff === 0
|
||||
}
|
||||
|
||||
/** Minimum PIN length enforced by Settings PIN change. */
|
||||
export const MIN_PIN_LENGTH = 6
|
||||
export const MAX_PIN_LENGTH = 32
|
||||
|
||||
export function validatePin(pin: string): string | null {
|
||||
if (pin.length < MIN_PIN_LENGTH) return `PIN must be at least ${MIN_PIN_LENGTH} digits`
|
||||
if (pin.length > MAX_PIN_LENGTH) return `PIN must be at most ${MAX_PIN_LENGTH} digits`
|
||||
if (!/^[0-9]+$/.test(pin)) return "PIN must be numeric"
|
||||
return null
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Version + upstream commit metadata for the About screen.
|
||||
*
|
||||
* `VERSION` is the SPA's `package.json` version, embedded by Vite at build
|
||||
* time via `import.meta.env`. We DO NOT import package.json directly — that
|
||||
* would force-bundle every `package.json` field into the client.
|
||||
*
|
||||
* `loadUpstreamSha()` fetches `/.upstream-sha` (a static file dropped by CI
|
||||
* containing the source commit hash). Returns `"unknown"` if the file is
|
||||
* missing in dev / preview.
|
||||
*/
|
||||
|
||||
declare global {
|
||||
interface ImportMetaEnv {
|
||||
/** Defined by Vite's `define` config or `vite-env.d.ts`. */
|
||||
readonly VITE_APP_VERSION?: string
|
||||
}
|
||||
}
|
||||
|
||||
export const VERSION =
|
||||
(typeof import.meta !== "undefined" && import.meta.env?.VITE_APP_VERSION) ||
|
||||
"0.1.0"
|
||||
|
||||
let cachedSha: string | null = null
|
||||
|
||||
export async function loadUpstreamSha(): Promise<string> {
|
||||
if (cachedSha !== null) return cachedSha
|
||||
if (typeof fetch === "undefined") {
|
||||
cachedSha = "unknown"
|
||||
return cachedSha
|
||||
}
|
||||
try {
|
||||
const res = await fetch("/.upstream-sha", { cache: "no-cache" })
|
||||
if (!res.ok) {
|
||||
cachedSha = "unknown"
|
||||
return cachedSha
|
||||
}
|
||||
const text = (await res.text()).trim()
|
||||
cachedSha = text.length > 0 ? text : "unknown"
|
||||
} catch {
|
||||
cachedSha = "unknown"
|
||||
}
|
||||
return cachedSha
|
||||
}
|
||||
|
||||
export function shortSha(sha: string): string {
|
||||
if (sha === "unknown") return sha
|
||||
return sha.slice(0, 7)
|
||||
}
|
||||
@@ -48,22 +48,9 @@ const FALLBACK_LUX: TrustedDApp[] = [
|
||||
},
|
||||
]
|
||||
|
||||
const FALLBACK_LIQUIDITY: TrustedDApp[] = [
|
||||
{
|
||||
name: "",
|
||||
url: "https://swap.",
|
||||
description: " DEX.",
|
||||
chainIds: [],
|
||||
category: "dex",
|
||||
},
|
||||
{
|
||||
name: "Liquidity Exchange",
|
||||
url: "https://exchange.",
|
||||
description: ".",
|
||||
chainIds: [],
|
||||
category: "exchange",
|
||||
},
|
||||
]
|
||||
// Tenant-specific fallbacks live in the tenant's wallet build, not in the
|
||||
// upstream lux/wallet source. Custom brands wire their own list via the
|
||||
// trusted-dapps fetch endpoint configured by appDomain.
|
||||
|
||||
function isHttpsUrl(value: string): boolean {
|
||||
try {
|
||||
@@ -111,12 +98,10 @@ function sanitiseEntries(entries: unknown): TrustedDApp[] {
|
||||
return out
|
||||
}
|
||||
|
||||
function selectFallback(appDomain: string | undefined): TrustedDApp[] {
|
||||
if (!appDomain) return FALLBACK_LUX
|
||||
const d = appDomain.toLowerCase()
|
||||
if (d.endsWith("") || d.endsWith("")) {
|
||||
return FALLBACK_LIQUIDITY
|
||||
}
|
||||
function selectFallback(_appDomain: string | undefined): TrustedDApp[] {
|
||||
// Wallet always ships the Lux fallback. Branded builds replace this list
|
||||
// at build time via WALLET_TRUSTED_DAPPS env override or fetch from a
|
||||
// tenant-managed `${appDomain}/api/trusted-dapps` endpoint.
|
||||
return FALLBACK_LUX
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user