Skip to content

Commit 29d76dd

Browse files
Merge pull request #29 from keepkey/feature-performance
Feature performance
2 parents dc5129b + a581f79 commit 29d76dd

64 files changed

Lines changed: 10366 additions & 4959 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# dependencies
22
**/node_modules
3-
3+
examples/*
44
# testing
55
**/coverage
66

CLAUDE.md

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Repository Overview
6+
7+
KeepKey Client is a browser extension for the KeepKey hardware wallet, built using React, TypeScript, and Vite with a Turborepo monorepo architecture. The extension supports Chrome and Firefox (Manifest V3).
8+
9+
## Development Commands
10+
11+
### Core Development
12+
```bash
13+
# Install dependencies (requires pnpm 9.9.0+, Node >=18.19.1)
14+
pnpm install
15+
16+
# Development mode with hot reload
17+
pnpm dev # Chrome
18+
pnpm dev:firefox # Firefox
19+
20+
# Production build
21+
pnpm build # Chrome
22+
pnpm build:firefox # Firefox
23+
24+
# Create distributable zip
25+
pnpm zip # Chrome (creates extension.zip)
26+
pnpm zip:firefox # Firefox
27+
```
28+
29+
### Testing & Quality
30+
```bash
31+
# Run E2E tests (builds and zips first)
32+
pnpm e2e # Chrome
33+
pnpm e2e:firefox # Firefox
34+
35+
# Type checking
36+
pnpm type-check
37+
38+
# Linting & formatting
39+
pnpm lint # Run ESLint with fixes
40+
pnpm lint:fix # Fix all linting issues
41+
pnpm prettier # Format code with Prettier
42+
43+
# Run specific E2E test
44+
pnpm -F @extension/e2e e2e
45+
```
46+
47+
### Clean & Reset
48+
```bash
49+
# Clean build artifacts
50+
pnpm clean:bundle # Remove dist and dist-zip
51+
pnpm clean:node_modules # Remove all node_modules
52+
pnpm clean:turbo # Clear Turbo cache
53+
pnpm clean # Full clean (all above)
54+
pnpm clean:install # Clean + reinstall dependencies
55+
```
56+
57+
## Architecture & Structure
58+
59+
### Monorepo Layout
60+
The project uses Turborepo with pnpm workspaces:
61+
62+
- **`chrome-extension/`**: Core extension with background script and manifest configuration
63+
- **`packages/`**: Shared packages used across the extension
64+
- `dev-utils`: Development utilities and manifest parser
65+
- `hmr`: Custom hot module reload plugin for Vite
66+
- `i18n`: Internationalization with type safety
67+
- `shared`: Shared hooks, components, and utilities
68+
- `storage`: Chrome storage API helpers with TypeScript
69+
- `ui`: Reusable UI components
70+
- `vite-config`: Shared Vite configuration
71+
- `zipper`: Build artifact packaging
72+
- **`pages/`**: Extension pages and entry points
73+
- `popup`: Main extension popup UI
74+
- `side-panel`: Chrome side panel (not available in Firefox)
75+
- `options`: Extension settings page
76+
- `content`: Content script for page injection
77+
- `content-ui`: Content script UI components
78+
- `devtools`: Developer tools integration
79+
80+
### Key Architecture Patterns
81+
82+
**Background Service Worker**: Located at `chrome-extension/src/background/index.ts`, handles:
83+
- KeepKey hardware wallet connection monitoring (polls `http://localhost:1646` every 5 seconds)
84+
- Chain-specific request handlers (Bitcoin, Ethereum, Cosmos, etc.)
85+
- State management and icon updates based on connection status
86+
- RPC request routing and approval flows
87+
88+
**Multi-Chain Support**: Each blockchain has a dedicated handler in `chrome-extension/src/background/chains/`:
89+
- EVM chains (Ethereum, BSC, Avalanche, etc.)
90+
- UTXO chains (Bitcoin, Litecoin, Dogecoin, etc.)
91+
- Cosmos ecosystem (THORChain, Maya, Osmosis)
92+
- Unique chains (Ripple)
93+
94+
**Storage Architecture**: Uses Chrome storage API with TypeScript wrappers:
95+
- `requestStorage`: Pending wallet requests
96+
- `web3ProviderStorage`: Web3 provider configuration
97+
- `exampleSidebarStorage`: UI state persistence
98+
99+
**Message Passing**: The extension uses Chrome runtime messaging for:
100+
- Background ↔ Popup communication
101+
- Content script ↔ Background communication
102+
- State change notifications (KEEPKEY_STATE_CHANGED events)
103+
104+
### Build System
105+
106+
**Vite Configuration**:
107+
- Each package/page has its own `vite.config.mts`
108+
- Shared config via `@extension/vite-config`
109+
- IIFE format for background script and content scripts
110+
- Source maps in dev, minification in production
111+
112+
**Manifest Generation**: Dynamic manifest.js with:
113+
- Conditional features (side panel only for Chrome)
114+
- Localization support via `__MSG_*` placeholders
115+
- All permissions required for hardware wallet interaction
116+
117+
## Environment Variables
118+
119+
Create `.env` from `.example.env` and define types in `vite-env.d.ts`:
120+
```typescript
121+
interface ImportMetaEnv {
122+
// Add your env var types here
123+
}
124+
```
125+
126+
## Extension Loading
127+
128+
### Chrome
129+
1. Navigate to `chrome://extensions`
130+
2. Enable "Developer mode"
131+
3. Click "Load unpacked"
132+
4. Select the `dist` folder
133+
134+
### Firefox
135+
1. Navigate to `about:debugging#/runtime/this-firefox`
136+
2. Click "Load Temporary Add-on"
137+
3. Select `manifest.json` from `dist` folder
138+
Note: Firefox extensions are temporary and need reloading after browser restart
139+
140+
## Working with Turborepo
141+
142+
```bash
143+
# Install dependency for root
144+
pnpm i <package> -w
145+
146+
# Install for specific workspace
147+
pnpm i <package> -F @extension/popup
148+
149+
# Run command in specific workspace
150+
pnpm -F @extension/e2e e2e
151+
152+
# Build specific packages
153+
turbo build --filter=@extension/popup
154+
```
155+
156+
## State Management
157+
158+
The extension tracks KeepKey connection states:
159+
- 0: Unknown
160+
- 1: Disconnected
161+
- 2: Connected
162+
- 3: Busy
163+
- 4: Errored
164+
- 5: Paired (address available)
165+
166+
Icon changes based on state (online/offline variants).
167+
168+
## Critical Files & Entry Points
169+
170+
- **Background Script**: `chrome-extension/src/background/index.ts`
171+
- **Popup Entry**: `pages/popup/src/index.tsx`
172+
- **Manifest Config**: `chrome-extension/manifest.js`
173+
- **Chain Handlers**: `chrome-extension/src/background/chains/*.ts`
174+
- **Storage Types**: `packages/storage/lib/types.ts`
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/usr/bin/env node
2+
3+
import * as esbuild from 'esbuild';
4+
import { resolve, dirname } from 'path';
5+
import { fileURLToPath } from 'url';
6+
7+
const __filename = fileURLToPath(import.meta.url);
8+
const __dirname = dirname(__filename);
9+
10+
const isDev = process.env.NODE_ENV === 'development';
11+
12+
async function build() {
13+
try {
14+
await esbuild.build({
15+
entryPoints: [resolve(__dirname, 'src/injected/injected.ts')],
16+
bundle: true,
17+
outfile: resolve(__dirname, 'public/injected.js'),
18+
format: 'iife',
19+
platform: 'browser',
20+
target: ['chrome90', 'firefox90'],
21+
minify: !isDev,
22+
sourcemap: isDev ? 'inline' : false,
23+
define: {
24+
'process.env.NODE_ENV': JSON.stringify(isDev ? 'development' : 'production'),
25+
},
26+
logLevel: 'info',
27+
});
28+
29+
console.log('✅ Injected script built successfully');
30+
} catch (error) {
31+
console.error('❌ Build failed:', error);
32+
process.exit(1);
33+
}
34+
}
35+
36+
build();

chrome-extension/package.json

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,31 @@
11
{
22
"name": "chrome-extension",
3-
"version": "0.3.10",
3+
"version": "0.3.13",
44
"description": "chrome extension - core settings",
55
"type": "module",
66
"scripts": {
77
"clean:node_modules": "pnpx rimraf node_modules",
88
"clean:turbo": "rimraf .turbo",
99
"clean": "pnpm clean:turbo && pnpm clean:node_modules",
10-
"build": "vite build",
11-
"dev": "cross-env __DEV__=true vite build --mode development",
10+
"build:injected": "node build-injected.mjs",
11+
"build": "pnpm build:injected && vite build",
12+
"dev": "cross-env __DEV__=true NODE_ENV=development pnpm build:injected && vite build --mode development",
1213
"test": "vitest run",
1314
"lint": "eslint ./ --ext .ts,.js,.tsx,.jsx",
1415
"lint:fix": "pnpm lint --fix",
1516
"prettier": "prettier . --write --ignore-path ../.prettierignore",
1617
"type-check": "tsc --noEmit"
1718
},
1819
"dependencies": {
19-
"@coinmasters/pioneer-sdk": "^4.8.26",
20-
"@coinmasters/types": "^4.8.5",
2120
"@extension/shared": "workspace:*",
2221
"@extension/storage": "workspace:*",
23-
"@pioneer-platform/helpers": "^4.0.12",
24-
"@pioneer-platform/pioneer-caip": "^9.2.32",
25-
"@pioneer-platform/pioneer-coins": "^9.2.23",
22+
"@pioneer-platform/helpers": "^4.0.13",
23+
"@pioneer-platform/pioneer-caip": "^9.2.38",
24+
"@pioneer-platform/pioneer-coins": "^9.11.0",
25+
"@pioneer-platform/pioneer-discovery": "^0.8.4",
26+
"@pioneer-platform/pioneer-sdk": "^4.21.14",
2627
"axios": "^1.7.7",
28+
"buffer": "^6.0.3",
2729
"coinselect": "^3.1.13",
2830
"ethers": "^6.13.2",
2931
"uuid": "^10.0.0",

0 commit comments

Comments
 (0)