Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ test-results/
playwright-report/
playwright/.cache/
coverage/

# Claude Code
.claude/settings.local.json
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,22 @@ cd glow-web
npm install
```

### Set up environment variables

1. Copy the example environment file:

```bash
cp example.env .env.local
```

2. Edit `.env.local` and add your Breez API key (required):

```
VITE_BREEZ_API_KEY="your_breez_api_key_here"
```

See `example.env` for all available configuration options.

### Start the development server

```bash
Expand Down
48 changes: 48 additions & 0 deletions example.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Glow Web Environment Variables
# Copy this file to .env.local and fill in your values

# =============================================================================
# REQUIRED
# =============================================================================

# Breez API key for SDK initialization
# Get your key at: https://breez.technology/sdk/
VITE_BREEZ_API_KEY=your_breez_api_key_here

# =============================================================================
# OPTIONAL
# =============================================================================

# Staging environment password (Preview deployments only)
# When set, users must enter this password to access the app
# VITE_STAGING_PASSWORD=

# Console logging override
# "true" = always enabled, "false" = always disabled
# Default: enabled in dev mode, disabled in production
# VITE_CONSOLE_LOGGING=true

# Passkey Relying Party ID for cross-app passkey sharing
# Enables passkeys created in Glow to work across other apps
# Requires server-side .well-known/webauthn configuration at the rpID domain
# Default: current hostname (passkeys only work on this domain)
# VITE_PASSKEY_RP_ID=keys.breez.technology

# Base path for subpath deployment
# Must include leading and trailing slashes
# Default: / (root)
# VITE_BASE_PATH=/glow/

# =============================================================================
# SERVER
# =============================================================================

# Server host binding
# Use "0.0.0.0" to allow LAN access (e.g., for testing on mobile devices)
# Default: localhost
# VITE_SERVER_HOST=0.0.0.0

# Allowed hosts for the server (comma-separated)
# Required when accessing via IP or custom hostname
# Example: 192.168.1.100,my-dev-machine.local
# VITE_SERVER_ALLOWED_HOSTS=
162 changes: 156 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"test:e2e:debug": "playwright test --debug"
},
"dependencies": {
"@breeztech/breez-sdk-spark": "0.10.0",
"@breeztech/breez-sdk-spark": "file:vendor/breez-sdk-spark.tgz",
"@headlessui/react": "^1.7.17",
"@zxing/browser": "^0.1.5",
"@zxing/library": "^0.21.3",
Expand Down
20 changes: 19 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ import RestorePage from './pages/RestorePage';
import GeneratePage from './pages/GeneratePage';
import GetRefundPage from './pages/GetRefundPage';
import BackupPage from './pages/BackupPage';
import PasskeyPage from './pages/PasskeyPage';
import SettingsPage from './pages/SettingsPage';
import FiatCurrenciesPage from './pages/FiatCurrenciesPage';
import { useIOSViewportFix } from './hooks/useIOSViewportFix';
import type { Seed } from '@breeztech/breez-sdk-spark';

type Screen = 'home' | 'restore' | 'generate' | 'wallet' | 'getRefund' | 'settings' | 'backup' | 'fiatCurrencies';
type Screen = 'home' | 'restore' | 'generate' | 'wallet' | 'getRefund' | 'settings' | 'backup' | 'fiatCurrencies' | 'passkey';

const AppContent: React.FC = () => {
const [currentScreen, setCurrentScreen] = useState<Screen>('home');
Expand All @@ -42,6 +44,12 @@ const AppContent: React.FC = () => {
setCurrentScreen('wallet');
};

// Navigate to wallet after passkey connect
const handlePasskeyConnect = async (seed: Seed, walletName: string) => {
await sdk.connectWithSeed(seed, false, walletName);
setCurrentScreen('wallet');
};

const handleLogout = async () => {
await sdk.handleLogout();
setCurrentScreen('home');
Expand All @@ -63,6 +71,16 @@ const AppContent: React.FC = () => {
<HomePage
onRestoreWallet={() => setCurrentScreen('restore')}
onCreateNewWallet={() => setCurrentScreen('generate')}
onUsePasskey={() => setCurrentScreen('passkey')}
prfAvailable={sdk.prfAvailable}
/>
);

case 'passkey':
return (
<PasskeyPage
onWalletRestored={handlePasskeyConnect}
onBack={() => setCurrentScreen('home')}
/>
);

Expand Down
7 changes: 6 additions & 1 deletion src/components/SideMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useEffect, useLayoutEffect, useState, useRef } from 'react';
import { createPortal } from 'react-dom';
import { Transition } from '@headlessui/react';
import { isPasskeyMode } from '@/services/passkeyService';
// Star positions around the logo (relative to center, in pixels)
const STARS = [
{ x: -28, y: -20, size: 3 },
Expand Down Expand Up @@ -29,6 +30,8 @@ const SideMenu: React.FC<SideMenuProps> = ({ isOpen, onClose, onLogout, onOpenSe
const [starsAnimating, setStarsAnimating] = useState(false);
const prevIsOpenRef = useRef(false);

const isPasskey = isPasskeyMode();

// Trigger star animation when sidebar opens
useEffect(() => {
if (isOpen && !prevIsOpenRef.current) {
Expand Down Expand Up @@ -245,7 +248,9 @@ const SideMenu: React.FC<SideMenuProps> = ({ isOpen, onClose, onLogout, onOpenSe
Logout Warning
</h3>
<p className="text-spark-text-secondary text-sm text-center mb-6">
Make sure you've saved your recovery phrase before logging out. You'll need it to access your funds again.
{isPasskey
? "You'll need to authenticate with the same passkey to access your funds again."
: "Make sure you've saved your recovery phrase before logging out. You'll need it to access your funds again."}
</p>

<div className="flex gap-3">
Expand Down
Loading