Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
44 changes: 44 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: CI

on:
push:
pull_request:

jobs:
build-and-test:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '20'
cache: npm

- name: Install dependencies
run: npm ci

- name: Build
run: npm run build

- name: Unit tests
run: npm run test:unit

- name: Install Playwright browser
run: npx playwright install --with-deps chromium

- name: E2E tests
run: npm run test:e2e

- name: Upload Playwright artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: playwright-artifacts
path: |
output/playwright/report
output/playwright/test-results
if-no-files-found: ignore
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ node_modules
dist
dist-ssr
*.local
output/playwright/
playwright-report/
test-results/

# Editor directories and files
.vscode/*
Expand Down
46 changes: 35 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
# Vanity ETH GPU
# Vanity SOL GPU

A fast Ethereum vanity address generator that runs entirely in your browser.
A fast Solana vanity address generator that runs entirely in your browser.

## Features

- **Multi-threaded** - Uses Web Workers for parallel address generation
- **Multi-threaded** - Uses Web Workers for parallel keypair generation
- **GPU-accelerated matching** - Uses WebGPU to parallelize Base58 vanity matching when available
- **Privacy First** - All computations run locally in your browser, no server communication
- **Custom Prefix/Suffix** - Find addresses starting or ending with your desired characters
- **Wallet + First Contract Targets** - Scan either the wallet address or its first `CREATE` deploy address (nonce 0)
- **Keystore Export** - Download encrypted keystore JSON files
- **Custom Prefix/Suffix** - Find addresses starting or ending with your desired Base58 characters
- **Wallet + Program ID Targets** - Scan either wallet addresses or program IDs
- **Keypair Export** - Download Solana-compatible keypair JSON files

## Requirements

- A modern browser (Chrome, Firefox, Edge, Safari)

## Usage

1. Choose target: wallet address or first contract address
2. Enter your desired prefix and/or suffix (hex characters: 0-9, a-f)
1. Choose target: wallet address or program ID
2. Enter your desired prefix and/or suffix (Base58 characters)
3. Click Generate and wait for a match
4. Once found, reveal the private key or download as encrypted keystore
4. Once found, reveal the secret key or download keypair JSON

## Security

- Disconnect from the internet before generating for maximum security
- Never share your private key
- Never share your secret key
- Always verify the address matches your requirements before use

## Development
Expand All @@ -38,14 +39,37 @@ npm run dev

# Build for production
npm run build

# Run unit tests
npm run test:unit

# Run browser E2E tests
npm run test:e2e

# Run full quality gate (build + unit + e2e)
npm run check
```

## Testing

- Unit tests use `vitest` and cover core Base58/keys logic.
- E2E tests use `@playwright/test` and exercise real UI flows in Chromium.
- CI runs `build`, `test:unit`, and `test:e2e` on every push/PR.
- For deterministic test runs, the dev server is started with `VITE_FORCE_BACKEND=cpu`.

## Tech Stack

- TypeScript
- Vite
- Web Workers
- @noble/secp256k1 for cryptography
- WebGPU
- @noble/curves (ed25519)

## Notes

- Runtime auto-benchmarks GPU hybrid mode vs CPU mode and picks the faster backend.
- If WebGPU is unavailable, the app falls back to CPU-only search.
- You can force a backend for troubleshooting with `VITE_FORCE_BACKEND=cpu` or `VITE_FORCE_BACKEND=gpu`.

## License

Expand Down
60 changes: 29 additions & 31 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,89 +4,87 @@
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vanity ETH GPU | Vanity Wallet & First Contract Address Generator</title>
<title>Vanity SOL GPU | Solana Vanity Wallet & Program ID Generator</title>

<meta
name="description"
content="Generate Ethereum vanity wallet addresses and first contract deploy addresses (CREATE nonce 0) directly in your browser with WebGPU, WASM, and CPU fallback."
content="Generate Solana vanity wallet addresses and vanity program IDs directly in your browser with WebGPU-accelerated matching and CPU fallback."
/>
<meta
name="keywords"
content="ethereum vanity address, ethereum address generator, vanity wallet, first contract address, webgpu ethereum, create nonce 0"
content="solana vanity address, solana vanity wallet, vanity program id, solana address generator, webgpu solana"
/>
<meta name="author" content="HODL Community" />
<meta name="application-name" content="Vanity ETH GPU" />
<meta name="apple-mobile-web-app-title" content="Vanity ETH GPU" />
<meta name="application-name" content="Vanity SOL GPU" />
<meta name="apple-mobile-web-app-title" content="Vanity SOL GPU" />
<meta name="robots" content="index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1" />
<meta name="referrer" content="strict-origin-when-cross-origin" />
<meta name="theme-color" content="#0b0c12" />
<meta name="theme-color" content="#05070d" />

<link rel="canonical" href="https://hodl-community.github.io/vanity-eth-gpu/" />
<link rel="alternate" href="https://hodl-community.github.io/vanity-eth-gpu/" hreflang="en" />
<link rel="canonical" href="https://hodl-community.github.io/vanity-sol-gpu/" />
<link rel="alternate" href="https://hodl-community.github.io/vanity-sol-gpu/" hreflang="en" />

<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="manifest" href="/site.webmanifest" />

<meta property="og:locale" content="en_US" />
<meta property="og:type" content="website" />
<meta property="og:site_name" content="Vanity ETH GPU" />
<meta property="og:url" content="https://hodl-community.github.io/vanity-eth-gpu/" />
<meta property="og:title" content="Vanity ETH GPU | Vanity Wallet & First Contract Address Generator" />
<meta property="og:site_name" content="Vanity SOL GPU" />
<meta property="og:url" content="https://hodl-community.github.io/vanity-sol-gpu/" />
<meta property="og:title" content="Vanity SOL GPU | Solana Vanity Wallet & Program ID Generator" />
<meta
property="og:description"
content="Generate Ethereum vanity wallet addresses and first contract deploy addresses in-browser with GPU acceleration."
content="Generate Solana vanity wallet addresses and program IDs in-browser with WebGPU-accelerated matching and CPU fallback."
/>
<meta property="og:image" content="https://hodl-community.github.io/vanity-eth-gpu/og-image.png" />
<meta property="og:image:secure_url" content="https://hodl-community.github.io/vanity-eth-gpu/og-image.png" />
<meta property="og:image" content="https://hodl-community.github.io/vanity-sol-gpu/og-image.svg" />
<meta property="og:image:secure_url" content="https://hodl-community.github.io/vanity-sol-gpu/og-image.svg" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta
property="og:image:alt"
content="Vanity ETH GPU: Ethereum vanity wallet and first-contract address generator."
content="Vanity SOL GPU: Solana vanity wallet and program ID generator."
/>

<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Vanity ETH GPU | Vanity Wallet & First Contract Address Generator" />
<meta name="twitter:title" content="Vanity SOL GPU | Solana Vanity Wallet & Program ID Generator" />
<meta
name="twitter:description"
content="GPU-accelerated in-browser Ethereum vanity scanner for wallets and first contract deploy addresses."
content="In-browser Solana vanity scanner with WebGPU-accelerated matching and CPU fallback."
/>
<meta name="twitter:image" content="https://hodl-community.github.io/vanity-eth-gpu/twitter-card.png" />
<meta name="twitter:image:alt" content="Vanity ETH GPU social card showing wallet and first-contract matching." />
<meta name="twitter:image" content="https://hodl-community.github.io/vanity-sol-gpu/twitter-card.svg" />
<meta name="twitter:image:alt" content="Vanity SOL GPU social card showing Solana vanity matching." />

<script type="application/ld+json">
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "WebSite",
"name": "Vanity ETH GPU",
"url": "https://hodl-community.github.io/vanity-eth-gpu/",
"name": "Vanity SOL GPU",
"url": "https://hodl-community.github.io/vanity-sol-gpu/",
"inLanguage": "en-US",
"description": "A privacy-first in-browser Ethereum vanity address generator with GPU acceleration."
"description": "A privacy-first in-browser Solana vanity address generator with GPU-accelerated matching."
},
{
"@type": "SoftwareApplication",
"name": "Vanity ETH GPU",
"name": "Vanity SOL GPU",
"applicationCategory": "SecurityApplication",
"operatingSystem": "Web",
"url": "https://hodl-community.github.io/vanity-eth-gpu/",
"image": "https://hodl-community.github.io/vanity-eth-gpu/og-image.png",
"url": "https://hodl-community.github.io/vanity-sol-gpu/",
"image": "https://hodl-community.github.io/vanity-sol-gpu/og-image.svg",
"inLanguage": "en-US",
"description": "Generate vanity Ethereum wallet and first-contract addresses with local-only key generation and WebGPU acceleration.",
"description": "Generate vanity Solana wallet addresses and program IDs with WebGPU-accelerated matching and local-only key generation.",
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "USD"
},
"featureList": [
"Wallet vanity address scanning",
"First contract deploy address scanning (CREATE nonce 0)",
"Program ID vanity scanning",
"WebGPU-accelerated Base58 matching",
"Local-only private key generation",
"Encrypted keystore export"
"Solana keypair JSON export"
]
}
]
Expand Down
20 changes: 20 additions & 0 deletions notes/mistakes.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,23 @@
- Mistake: I interpreted “remove EIP-55” as removing the feature instead of removing the wording in the selector, and merged that broader behavior change.
- Avoid: Confirm scope by mapping the request to explicit targets (label text vs runtime logic) before editing behavior paths.
- Cleanup: Restore the previous behavior and apply only the requested copy change in a follow-up PR.

- Mistake: I tried to remove files using `rm -rf` in this environment, and the command was blocked by policy.
- Avoid: Prefer `apply_patch` delete hunks for tracked-file removals so cleanup is tool-policy compatible.
- Cleanup: Re-run the file removals via `apply_patch` and verify deletions with `git status --short`.

- Mistake: I imported `@noble/curves/ed25519` without the `.js` extension, which failed TypeScript module resolution under the repo’s ESM/bundler settings.
- Avoid: For `@noble/*` subpath imports in this setup, use explicit `.js` subpath imports from the start and run a build after dependency swaps.
- Cleanup: Replace imports with `@noble/curves/ed25519.js` and rerun `npm run build` to confirm.

- Mistake: I assumed typed-array buffers would satisfy `ArrayBuffer` transfer typings, but under strict TS they were inferred as `ArrayBufferLike`, causing compile errors in worker postMessage and `queue.writeBuffer`.
- Avoid: Validate transfer/buffer boundaries early for worker/GPU code; normalize with explicit `Uint8Array#slice()` copies when strict buffer types are required.
- Cleanup: Send typed arrays directly through worker messages (or copy into concrete `ArrayBuffer`), and pass a concrete copy into `queue.writeBuffer` before building.

- Mistake: I ran `mkdir -p tests/...` without setting the repo `workdir`, so the folders were created outside the project context.
- Avoid: Always include `workdir` on filesystem mutations, even for simple directory creation commands.
- Cleanup: Re-run directory creation with the correct repo `workdir` and verify with `pwd` + `ls`.

- Mistake: I assumed the local Playwright skill wrapper command (`playwright-cli`) was still available from `@playwright/mcp`; current package exposes `playwright-mcp` instead.
- Avoid: Verify CLI binary names with `npm pkg get bin` (or inspect installed package metadata) before scripting around a wrapper.
- Cleanup: Use a fallback test strategy (`@playwright/test`) when wrapper tooling is not operational in the environment, and document the discrepancy.
Loading
Loading