Skip to content

Commit 106b9c6

Browse files
authored
Merge pull request #1 from AztecProtocol/gj/nigthly_update
nigthly update
2 parents d9f6d0d + 9a8613f commit 106b9c6

23 files changed

+2216
-601
lines changed

CLAUDE.MD

Lines changed: 376 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,376 @@
1+
# Claude Context: Demo Wallet
2+
3+
## Project Overview
4+
5+
This is an Aztec wallet application built with Electron that allows dApps to interact with user accounts through a secure browser extension interface. The wallet manages private keys, handles transaction simulation/execution, and provides authorization flows for dApp requests.
6+
7+
## Architecture
8+
9+
### Core Components
10+
11+
1. **Electron App (Main Process)**
12+
- Native desktop application
13+
- Manages wallet instances via worker threads
14+
- Handles IPC between UI and wallet logic
15+
- Located in `/app`
16+
17+
2. **Browser Extension**
18+
- Provides interface between dApps and wallet
19+
- Supports Chromium-based browsers (Chrome, Brave, Edge) and Firefox
20+
- Located in `/extension` (separate repository)
21+
- Communicates with wallet via WebSocket on port **8765**
22+
23+
3. **Wallet Worker (`wallet-worker.ts`)**
24+
- Manages PXE (Private Execution Environment) instances
25+
- Handles wallet operations (simulate, send, register contracts)
26+
- Maintains session state per network (chainId-version)
27+
- Creates separate wallet instances per app for authorization isolation
28+
29+
4. **WebSocket Worker (`ws-worker.ts`)**
30+
- Runs WebSocket server on port 8765
31+
- Bridges extension ↔ wallet communication
32+
- **Temporary**: Should use Native Messaging API instead
33+
34+
### Key Architectural Decisions
35+
36+
#### Single PXE Instance Per Session
37+
38+
**Critical**: Each network session (identified by `chainId-version`) has **one shared PXE instance** used by all apps. Multiple PXE instances per session causes JavaScript Maps to get out of sync with LMDB, leading to `Cannot read properties of undefined (reading 'getValuesAsync')` errors.
39+
40+
**Structure** (`wallet-worker.ts`):
41+
```typescript
42+
type SessionData = {
43+
sharedResources: Promise<{
44+
pxe: any; // Shared across all apps
45+
node: any; // Shared across all apps
46+
db: any; // Shared across all apps
47+
pendingAuthorizations: Map<string, any>;
48+
}>;
49+
wallets: Map<string, Promise<{ external: ExternalWallet; internal: InternalWallet }>>;
50+
};
51+
52+
const RUNNING_SESSIONS = new Map<string, SessionData>();
53+
```
54+
55+
- **Session Level**: One PXE per network, indexed by `sessionId`
56+
- **App Level**: Separate `ExternalWallet` and `InternalWallet` instances per `appId`
57+
- **Why**: PXE's `NoteDataProvider` maintains JavaScript Maps that must stay in sync with LMDB
58+
59+
#### External vs Internal Wallets
60+
61+
- **ExternalWallet**: Handles requests from dApps (via extension)
62+
- **InternalWallet**: Handles internal requests (UI, account management)
63+
- Both share the same PXE, node, db, and authorization state
64+
65+
#### Authorization Flow
66+
67+
1. dApp sends request → Extension → WebSocket → Wallet Worker
68+
2. Wallet simulates transaction and creates `AuthorizationRequest`
69+
3. Authorization dialog shown to user in Electron UI
70+
4. User approves/denies → Response sent back through chain
71+
5. Authorized operations can be persisted (e.g., `simulateTx` with payload hash)
72+
73+
## Database Structure
74+
75+
### WalletDB (`wallet-db.ts`)
76+
77+
Uses LMDB (via `@aztec/kv-store/lmdb-v2`) for persistent storage:
78+
79+
- **accounts**: Account data indexed by address
80+
- **aliases**: Human-readable names for addresses
81+
- **interactions**: History of all wallet operations
82+
- **authorizations**: Persistent authorization grants (keyed by `appId:method:item`)
83+
- **txSimulations**: Cached simulation results with metadata
84+
- Stores: `{ simulationResult, txRequest, metadata: { from, embeddedPaymentMethodFeePayer } }`
85+
- **bridgedFeeJuice**: Fee payment token management
86+
87+
### PXE Storage
88+
89+
PXE maintains its own LMDB database at `~/keychain/pxe-${rollupAddress}`:
90+
- Note synchronization data
91+
- Contract artifacts and instances
92+
- Encrypted notes per account
93+
94+
## Common Issues & Fixes
95+
96+
### 1. PXE Note Synchronization Error
97+
98+
**Symptom**: `Cannot read properties of undefined (reading 'getValuesAsync')` after deleting authorizations or creating new accounts.
99+
100+
**Root Cause**: Multiple PXE instances sharing the same LMDB database. When `addScope()` is called and the scope already exists in LMDB, it returns early without populating JavaScript Maps.
101+
102+
**Solution**:
103+
1. Ensure only one PXE per session (fixed in `wallet-worker.ts`)
104+
2. Defensive fix in PXE's `note_data_provider.js` for lazy Map initialization (see patch file)
105+
106+
**Files**:
107+
- `app/src/workers/wallet-worker.ts`: Single PXE per session
108+
- `app/node_modules/@aztec/pxe/dest/storage/note_data_provider/note_data_provider.js`: Defensive fix
109+
- `pxe-note-provider-map-sync-fix.patch`: Patch file for Aztec repo
110+
111+
### 2. Batch Authorization Denial
112+
113+
**Symptom**: Operations stuck in "requesting authorization" after user clicks "Deny All".
114+
115+
**Root Cause**: Batch method in `external-wallet.ts` didn't catch authorization denial error.
116+
117+
**Solution**: Wrap `requestAuthorization` in try-catch and mark items as ERROR on denial.
118+
119+
**File**: `app/src/wallet/core/external-wallet.ts`
120+
121+
### 3. Execution Trace Performance
122+
123+
**Symptom**: Unreasonable delay when opening execution trace dialog.
124+
125+
**Root Cause**: `getExecutionTrace()` was creating a new `DecodingCache` instance on every call.
126+
127+
**Solution**: Use shared `this.decodingCache` from `BaseNativeWallet`.
128+
129+
**File**: `app/src/wallet/core/internal-wallet.ts:196-229`
130+
131+
### 4. Stats Not Showing After Authorization
132+
133+
**Symptom**: Simulation stats visible during authorization but not when clicking stored interactions.
134+
135+
**Root Cause**: `getExecutionTrace()` wasn't returning stats from stored simulations.
136+
137+
**Solution**: Update return type and extract stats from both utility traces and tx simulations.
138+
139+
**Files**:
140+
- `app/src/wallet/core/internal-wallet.ts`
141+
- `app/src/wallet/database/wallet-db.ts`
142+
143+
### 5. Utility Trace Confusion
144+
145+
**Symptom**: `getUtilityTrace()` returning data for tx simulations.
146+
147+
**Root Cause**: Method didn't check if `utilityTrace` field actually existed in stored data.
148+
149+
**Solution**: Add check `if (!parsed.utilityTrace) return undefined;`
150+
151+
**File**: `app/src/wallet/database/wallet-db.ts`
152+
153+
## Important Code Patterns
154+
155+
### Fee Payer Information
156+
157+
When a transaction includes `embeddedPaymentMethodFeePayer`, the app is providing the fee payment method:
158+
- Extract from `opts.fee?.embeddedPaymentMethodFeePayer` or `executionPayload.feePayer`
159+
- Store in metadata when saving simulations
160+
- Display in authorization dialogs and execution traces with success alert
161+
162+
### MulticallEntrypoint Detection
163+
164+
When `from` is set to `AztecAddress.ZERO`, the request uses MulticallEntrypoint:
165+
- Does not execute from any user account
166+
- Display reassuring info alert in authorization dialogs
167+
168+
### Simulation Title Generation
169+
170+
Use `generateSimulationTitle()` from `simulation-utils.ts`:
171+
- Includes contract names and function calls
172+
- Handles fee payer information
173+
- Provides readable titles for UI
174+
175+
### Zod Schemas for IPC
176+
177+
All data crossing IPC boundaries must have Zod schemas:
178+
- `InternalWalletInterfaceSchema` in `wallet-internal-interface.ts`
179+
- Serialization/deserialization handled automatically
180+
- Update schemas when adding new fields to return types
181+
182+
## UI Components
183+
184+
### Authorization Dialogs
185+
186+
- `AuthorizeSendTxContent.tsx`: Send transaction authorization
187+
- `AuthorizeSimulateTxContent.tsx`: Simulation authorization
188+
- Display fee payer and MulticallEntrypoint alerts
189+
190+
### Execution Trace Display
191+
192+
- `ExecutionTraceDisplay.tsx`: Shows decoded execution with timing stats
193+
- `ExecutionTraceDialog.tsx`: Modal dialog for viewing stored interactions
194+
- `SimulationStatsDisplay`: Collapsible accordion with function hierarchy and RPC calls
195+
196+
### Features
197+
198+
- Collapsible simulation timing stats (default collapsed)
199+
- Function call hierarchy with tree visualization
200+
- RPC calls table sorted by total time
201+
- Call authorization display
202+
- Automatic contract/function decoding via `DecodingCache`
203+
204+
## Development Setup
205+
206+
### Requirements
207+
208+
- Node.js v22
209+
- yarn
210+
- Running Aztec node (local or remote)
211+
212+
### Running
213+
214+
```bash
215+
# Wallet
216+
cd app
217+
yarn install
218+
yarn start
219+
220+
# Extension
221+
cd extension
222+
yarn install
223+
yarn dev # Launches browser with extension
224+
```
225+
226+
### Port Configuration
227+
228+
- **WebSocket**: Port 8765 (configurable in `ws-worker.ts`)
229+
- **Node RPC**: Default port 8080 (configured in `networks.ts`)
230+
231+
## Testing Scenarios
232+
233+
### Creating and Revoking Authorizations
234+
235+
**Critical Test**: This scenario previously triggered the PXE synchronization bug:
236+
237+
1. Create account "ECDSAR1 0"
238+
2. Complete app onboarding (simulations, transactions, contract registrations)
239+
3. Revoke ALL authorizations for the app
240+
4. Create new account "ECDSAR1 1"
241+
5. Attempt app onboarding again
242+
243+
**Expected**: Should work without errors
244+
**Previously**: Failed with `getValuesAsync` undefined error
245+
246+
### Batch Operations
247+
248+
Test "Deny All" in batch authorization dialogs:
249+
- Should mark all pending operations as ERROR
250+
- Should not leave operations stuck in "requesting authorization"
251+
252+
### Execution Trace Performance
253+
254+
- Opening execution trace dialog should be instant
255+
- No delays or multiple decoding cache instantiations
256+
257+
## Code Quality Guidelines
258+
259+
### Error Handling
260+
261+
- Always wrap authorization requests in try-catch
262+
- Contextualize errors with relevant data (use `contextualizeError`)
263+
- Log meaningful messages at appropriate levels
264+
265+
### Resource Management
266+
267+
- Reuse shared resources (PXE, node client, caches)
268+
- Never create duplicate PXE instances for the same session
269+
- Clean up event listeners when destroying wallet instances
270+
271+
### Logging
272+
273+
- Use `createProxyLogger` for worker threads
274+
- Include context in logger names (e.g., `wallet:external:${appId}`)
275+
- Avoid excessive logging in production code
276+
- Debug logs helped identify the PXE multi-instance issue
277+
278+
### TypeScript
279+
280+
- Use strict typing for operation display data
281+
- Define explicit types for IPC message parameters
282+
- Avoid `any` except for Zod schemas (with `@ts-ignore`)
283+
284+
## Known Limitations
285+
286+
1. **WebSocket Communication**: Should use Native Messaging API instead
287+
2. **Port Management**: Port 8765 must be available
288+
3. **Single Network**: Currently only supports one rollup version at a time
289+
4. **Authorization Persistence**: Limited to `appId:method:item` format
290+
291+
## Future Improvements
292+
293+
1. **Native Messaging**: Replace WebSocket with browser's native extension-to-app communication
294+
2. **Multi-Network**: Support multiple networks simultaneously
295+
3. **Account Derivation**: BIP-44 HD wallet support
296+
4. **Hardware Wallets**: Ledger/Trezor integration
297+
5. **Fee Estimation**: Better gas estimation and fee payment methods
298+
6. **Transaction History**: Enhanced filtering and search
299+
7. **Contact Book**: Address aliases and management
300+
301+
## File Reference
302+
303+
### Critical Files
304+
305+
- `app/src/workers/wallet-worker.ts`: Session and PXE management
306+
- `app/src/wallet/core/external-wallet.ts`: dApp request handling
307+
- `app/src/wallet/core/internal-wallet.ts`: Internal operations
308+
- `app/src/wallet/database/wallet-db.ts`: Persistent storage
309+
- `app/src/wallet/operations/*.ts`: Operation implementations
310+
- `app/src/ipc/wallet-internal-interface.ts`: IPC type definitions
311+
312+
### UI Files
313+
314+
- `app/src/ui/components/authorization/*`: Authorization dialogs
315+
- `app/src/ui/components/dialogs/*`: Modals and dialogs
316+
- `app/src/ui/components/shared/*`: Reusable components
317+
- `app/src/ui/components/sections/*`: Main UI sections
318+
319+
### Configuration
320+
321+
- `app/src/config/networks.ts`: Network definitions
322+
- `app/package.json`: Dependencies and scripts
323+
- `README.md`: Setup instructions
324+
325+
## Debugging Tips
326+
327+
### Check PXE Instance Count
328+
329+
Look for log messages:
330+
```
331+
[PXE-INIT] Creating NEW session with shared PXE instance for sessionId=...
332+
[PXE-INIT] Reusing existing shared PXE instance for sessionId=...
333+
```
334+
335+
Should only see one "Creating NEW" per network session.
336+
337+
### Authorization Flow
338+
339+
Check logs for:
340+
```
341+
Received external message: ...
342+
Received internal message: ...
343+
```
344+
345+
External = from dApp, Internal = from wallet UI
346+
347+
### Note Synchronization
348+
349+
If errors occur, check:
350+
- `~/keychain/aztec-keychain-debug.log` for full logs
351+
- Whether multiple PXE instances are being created
352+
- LMDB data directory: `~/keychain/pxe-${rollupAddress}`
353+
354+
### Performance Issues
355+
356+
- Check if `DecodingCache` is being reused (should be singleton per wallet)
357+
- Monitor database query times
358+
- Look for unnecessary re-renders in React components
359+
360+
## Version Information
361+
362+
- **Node.js**: v22
363+
- **Electron**: (check `app/package.json`)
364+
- **Aztec SDK**: (check `app/package.json` for `@aztec/*` packages)
365+
- **React**: (check `app/package.json`)
366+
367+
## Related Repositories
368+
369+
- **Extension**: `../extension` (sibling directory)
370+
- **Aztec Packages**: Official Aztec monorepo (for PXE patches)
371+
372+
## Patch Files
373+
374+
- `pxe-note-provider-map-sync-fix.patch`: Fix for PXE note synchronization issue
375+
- Apply to: `yarn-project/pxe/src/storage/note_data_provider/note_data_provider.ts`
376+
- Command: `git apply /path/to/patch` or `git am /path/to/patch`

0 commit comments

Comments
 (0)