Skip to content

Commit 86ecc2d

Browse files
author
Esau
committed
init
fix
1 parent 4230e93 commit 86ecc2d

File tree

17 files changed

+7128
-0
lines changed

17 files changed

+7128
-0
lines changed

test-wallet-webapp/.gitignore

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
node_modules
11+
dist
12+
dist-ssr
13+
*.local
14+
15+
# Editor directories and files
16+
.vscode/*
17+
!.vscode/extensions.json
18+
.idea
19+
.DS_Store
20+
*.suo
21+
*.ntvs*
22+
*.njsproj
23+
*.sln
24+
*.sw?

test-wallet-webapp/README.md

Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,289 @@
1+
# Aztec Wallet Web App Tutorial
2+
3+
This tutorial demonstrates how to build a browser-based wallet application for Aztec using React and Vite. It showcases creating wallets, deploying contracts, and interacting with the Aztec network directly from a web browser.
4+
5+
## What You'll Build
6+
7+
A web application that demonstrates three core Aztec operations:
8+
9+
1. **Create Wallet** - Initialize a TestWallet with a Schnorr account
10+
2. **Deploy Contract** - Deploy the PrivateVoting contract to Aztec
11+
3. **Cast Vote** - Interact with the deployed contract
12+
13+
## Prerequisites
14+
15+
- Node.js v18 or higher
16+
- Yarn package manager
17+
- A running Aztec sandbox instance
18+
19+
## Quick Start
20+
21+
### 1. Install Dependencies
22+
23+
```bash
24+
yarn install
25+
```
26+
27+
### 2. Start Aztec Sandbox
28+
29+
```bash
30+
aztec start --sandbox
31+
```
32+
33+
The sandbox must be running on `http://localhost:8080` before starting the app.
34+
35+
### 3. Start Development Server
36+
37+
```bash
38+
yarn dev
39+
```
40+
41+
Open your browser to `http://localhost:5173` and click through the steps.
42+
43+
---
44+
45+
## Creating From Scratch
46+
47+
If you want to build this project from scratch, follow these steps:
48+
49+
### 1. Create Vite Project
50+
51+
```bash
52+
yarn create vite testwallet-webapp-tutorial-new --template react-ts
53+
cd testwallet-webapp-tutorial-new
54+
yarn install
55+
```
56+
57+
### 2. Install Aztec Dependencies
58+
59+
```bash
60+
yarn add @aztec/[email protected] \
61+
62+
63+
64+
```
65+
66+
### 3. Install Build Tooling Dependencies
67+
68+
```bash
69+
yarn add -D vite-plugin-node-polyfills @types/node
70+
```
71+
72+
### 4. Configure Vite
73+
74+
Replace the default `vite.config.ts` with:
75+
76+
```typescript
77+
import { defineConfig, searchForWorkspaceRoot } from 'vite'
78+
import react from '@vitejs/plugin-react'
79+
import { nodePolyfills, type PolyfillOptions } from "vite-plugin-node-polyfills";
80+
81+
const nodeModulesPath = `${searchForWorkspaceRoot(process.cwd())}/node_modules`;
82+
83+
// Workaround for vite-plugin-node-polyfills module resolution bug
84+
// See: https://github.com/davidmyersdev/vite-plugin-node-polyfills/issues/81
85+
const nodePolyfillsFix = (options?: PolyfillOptions | undefined) => {
86+
return {
87+
...nodePolyfills(options),
88+
resolveId(source: string) {
89+
const m =
90+
/^vite-plugin-node-polyfills\/shims\/(buffer|global|process)$/.exec(
91+
source,
92+
);
93+
if (m) {
94+
return `${nodeModulesPath}/vite-plugin-node-polyfills/shims/${m[1]}/dist/index.cjs`;
95+
}
96+
},
97+
};
98+
};
99+
100+
export default defineConfig({
101+
server: {
102+
// Headers needed for bb WASM to work in multithreaded mode
103+
headers: {
104+
"Cross-Origin-Opener-Policy": "same-origin",
105+
"Cross-Origin-Embedder-Policy": "require-corp",
106+
},
107+
},
108+
plugins: [
109+
react(),
110+
nodePolyfillsFix({
111+
include: ["buffer", "path", "process", "net", "tty"],
112+
}),
113+
],
114+
optimizeDeps: {
115+
include: ['pino', 'pino/browser'],
116+
exclude: ['@aztec/noir-noirc_abi', '@aztec/noir-acvm_js', '@aztec/bb.js', '@aztec/noir-noir_js']
117+
},
118+
})
119+
```
120+
121+
---
122+
123+
## Understanding the Configuration
124+
125+
### Why These Vite Settings Are Required
126+
127+
Aztec's browser support requires several special configurations:
128+
129+
#### 1. WASM Multithreading Headers
130+
131+
```typescript
132+
headers: {
133+
"Cross-Origin-Opener-Policy": "same-origin",
134+
"Cross-Origin-Embedder-Policy": "require-corp",
135+
}
136+
```
137+
138+
Aztec uses WebAssembly with SharedArrayBuffer for multithreaded cryptographic operations. Modern browsers require these CORS headers to enable SharedArrayBuffer for security reasons.
139+
140+
#### 2. Node.js Polyfills
141+
142+
```typescript
143+
nodePolyfillsFix({
144+
include: ["buffer", "path", "process", "net", "tty"],
145+
})
146+
```
147+
148+
Aztec SDK packages (`@aztec/aztec.js`, `@aztec/accounts`, etc.) were originally designed for Node.js and depend on Node.js APIs that don't exist in browsers:
149+
150+
- **`buffer`** - Binary data handling used by cryptographic operations and WASM modules
151+
- **`process`** - Environment variables and process information
152+
- **`path`** - File path utilities used by module resolution
153+
- **`net` & `tty`** - Required by the Pino logger used throughout Aztec SDK
154+
155+
The `vite-plugin-node-polyfills` provides browser-compatible implementations of these APIs.
156+
157+
**Note**: The `nodePolyfillsFix` wrapper is a workaround for a module resolution bug in vite-plugin-node-polyfills v0.19.0+ where the plugin's polyfill imports fail to resolve correctly during Vite's optimization phase, causing runtime errors even though builds succeed. The fix manually resolves polyfill paths to their absolute file system locations.
158+
159+
#### 3. Dependency Optimization
160+
161+
```typescript
162+
optimizeDeps: {
163+
include: ['pino', 'pino/browser'],
164+
exclude: ['@aztec/noir-noirc_abi', '@aztec/noir-acvm_js', '@aztec/bb.js', '@aztec/noir-noir_js']
165+
}
166+
```
167+
168+
- **Include**: Pre-bundle the Pino logger for better performance
169+
- **Exclude**: Prevent Vite from optimizing Aztec's WASM modules, which would break their loading mechanism
170+
171+
---
172+
173+
## Key Code Patterns
174+
175+
### Connecting to Aztec
176+
177+
```typescript
178+
import { createAztecNodeClient } from '@aztec/aztec.js/node'
179+
import { getPXEConfig } from '@aztec/pxe/client/lazy';
180+
import { TestWallet } from '@aztec/test-wallet/client/lazy';
181+
182+
const nodeURL = 'http://localhost:8080';
183+
const aztecNode = await createAztecNodeClient(nodeURL);
184+
const config = getPXEConfig();
185+
config.dataDirectory = 'pxe';
186+
const wallet = await TestWallet.create(aztecNode, config);
187+
```
188+
189+
### Creating a Schnorr Account
190+
191+
```typescript
192+
import { getInitialTestAccountsData } from '@aztec/accounts/testing';
193+
194+
const [accountData] = await getInitialTestAccountsData();
195+
const accountManager = await wallet.createSchnorrAccount(
196+
accountData.secret,
197+
accountData.salt,
198+
accountData.signingKey
199+
);
200+
const accountAddress = accountManager.address;
201+
```
202+
203+
### Deploying a Contract
204+
205+
```typescript
206+
import { PrivateVotingContract } from '@aztec/noir-contracts.js/PrivateVoting';
207+
208+
const deployedContract = await PrivateVotingContract.deploy(wallet, address)
209+
.send({ from: address })
210+
.deployed();
211+
```
212+
213+
### Calling Contract Methods
214+
215+
```typescript
216+
import { AztecAddress } from '@aztec/aztec.js/addresses'
217+
218+
const contract = await PrivateVotingContract.at(contractAddress, wallet);
219+
await contract.methods.cast_vote(AztecAddress.random())
220+
.send({ from: address })
221+
.wait();
222+
```
223+
224+
---
225+
226+
## Troubleshooting
227+
228+
### "Buffer is not defined" or "process is not defined"
229+
230+
**Problem**: Node.js polyfills aren't loading correctly.
231+
232+
**Solution**: Ensure you're using the `nodePolyfillsFix` wrapper in your Vite config (not the plain `nodePolyfills` plugin). The wrapper fixes a module resolution bug in the polyfills plugin.
233+
234+
### WASM Loading Errors
235+
236+
**Problem**: Errors about SharedArrayBuffer or WASM initialization failures.
237+
238+
**Solution**: Verify the CORS headers in your Vite config:
239+
```typescript
240+
headers: {
241+
"Cross-Origin-Opener-Policy": "same-origin",
242+
"Cross-Origin-Embedder-Policy": "require-corp",
243+
}
244+
```
245+
246+
Check browser console - these headers must be present in the response.
247+
248+
### Module Not Found Errors
249+
250+
**Problem**: Cannot resolve Aztec packages or their dependencies.
251+
252+
**Solution**:
253+
- Ensure all Aztec packages are on the **same version** (e.g., `3.0.0-devnet.5`)
254+
- Verify WASM modules are excluded in `optimizeDeps.exclude`
255+
- Clear Vite cache: `rm -rf node_modules/.vite`
256+
257+
### "Cannot connect to PXE" or Network Errors
258+
259+
**Problem**: Application can't reach the Aztec sandbox.
260+
261+
**Solution**:
262+
- Ensure Aztec sandbox is running: `aztec start --sandbox`
263+
- Verify it's accessible at `http://localhost:8080`
264+
- Check CORS if sandbox is on a different port
265+
266+
---
267+
268+
## Project Structure
269+
270+
```
271+
test-wallet-webapp/
272+
├── src/
273+
│ ├── App.tsx # Main application component
274+
│ ├── main.tsx # Application entry point
275+
│ ├── consoleInterceptor.ts # Console output capture utility
276+
│ └── ...
277+
├── vite.config.ts # Vite configuration with Aztec compatibility
278+
├── package.json # Dependencies
279+
└── README.md # This file
280+
```
281+
282+
---
283+
284+
## Learn More
285+
286+
- [Aztec Documentation](https://docs.aztec.network/)
287+
- [Aztec.js API Reference](https://docs.aztec.network/apis/aztecjs)
288+
- [Vite Documentation](https://vitejs.dev/)
289+
- [vite-plugin-node-polyfills Issue #81](https://github.com/davidmyersdev/vite-plugin-node-polyfills/issues/81)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import js from '@eslint/js'
2+
import globals from 'globals'
3+
import reactHooks from 'eslint-plugin-react-hooks'
4+
import reactRefresh from 'eslint-plugin-react-refresh'
5+
import tseslint from 'typescript-eslint'
6+
import { defineConfig, globalIgnores } from 'eslint/config'
7+
8+
export default defineConfig([
9+
globalIgnores(['dist']),
10+
{
11+
files: ['**/*.{ts,tsx}'],
12+
extends: [
13+
js.configs.recommended,
14+
tseslint.configs.recommended,
15+
reactHooks.configs.flat.recommended,
16+
reactRefresh.configs.vite,
17+
],
18+
languageOptions: {
19+
ecmaVersion: 2020,
20+
globals: globals.browser,
21+
},
22+
},
23+
])

test-wallet-webapp/index.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>testwallet-webapp-tutorial-new</title>
8+
</head>
9+
<body>
10+
<div id="root"></div>
11+
<script type="module" src="/src/main.tsx"></script>
12+
</body>
13+
</html>

test-wallet-webapp/package.json

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"name": "testwallet-webapp-tutorial-new",
3+
"private": true,
4+
"version": "0.0.0",
5+
"type": "module",
6+
"scripts": {
7+
"dev": "vite",
8+
"build": "tsc -b && vite build",
9+
"lint": "eslint .",
10+
"preview": "vite preview"
11+
},
12+
"dependencies": {
13+
"@aztec/accounts": "3.0.0-devnet.5",
14+
"@aztec/aztec.js": "3.0.0-devnet.5",
15+
"@aztec/test-wallet": "3.0.0-devnet.5",
16+
"@aztec/noir-contracts.js": "3.0.0-devnet.5",
17+
"react": "^19.2.0",
18+
"react-dom": "^19.2.0"
19+
},
20+
"devDependencies": {
21+
"@eslint/js": "^9.39.1",
22+
"@types/node": "^24.10.1",
23+
"@types/react": "^19.2.5",
24+
"@types/react-dom": "^19.2.3",
25+
"@vitejs/plugin-react": "^5.1.1",
26+
"eslint": "^9.39.1",
27+
"eslint-plugin-react-hooks": "^7.0.1",
28+
"eslint-plugin-react-refresh": "^0.4.24",
29+
"globals": "^16.5.0",
30+
"typescript": "~5.9.3",
31+
"typescript-eslint": "^8.46.4",
32+
"vite": "^7.2.4",
33+
"vite-plugin-node-polyfills": "^0.24.0"
34+
}
35+
}

test-wallet-webapp/public/vite.svg

Lines changed: 1 addition & 0 deletions
Loading

0 commit comments

Comments
 (0)