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
24 changes: 24 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,3 +280,27 @@ Required for Matomo integration:
- **Platform**: Netlify (config in `netlify.toml`)
- **Next.js Integration**: Uses `@netlify/plugin-nextjs` for seamless Netlify and Next.js compatibility
- **Monitoring**: Matomo analytics integration

## Adding Products (Wallets, Exchanges, etc.)

When implementing product additions or updates (wallets, exchanges, layer 2s, etc.), **both data AND assets are required**. See detailed guides in `docs/`:

- **Wallets**: See `docs/adding-wallets.md` for complete implementation guide

### Critical Requirements for Product Additions

1. **Always include the image/logo asset** - Product listings require an image file in `public/images/`. The data entry will fail TypeScript compilation without the corresponding image import.

2. **Two-step implementation**:
- Step 1: Add the image file to `public/images/{category}/`
- Step 2: Add the data entry with import statement

3. **Verify chain names** - When adding `supported_chains`, use exact names from `src/data/chains.ts`. Common mistakes:
- "Optimism" should be "OP Mainnet"
- "Polygon" could be "Polygon zkEVM" (chainId 1101) - verify the specific chain
Comment on lines +298 to +300
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part feels redundant from above, but claude also didn't follow these instructions:

### Type-Safe Chain Names

This project enforces type-safe chain names via TypeScript. When working with layer 2 networks or wallet data:

**Critical Files:**

- `src/data/chains.ts` - Canonical source of all chain names (auto-updated weekly)
- `src/lib/types.ts` - Defines `ChainName` type derived from chains.ts
- `src/data/networks/networks.ts` - Uses `chainName: ChainName`
- `src/data/wallets/wallet-data.ts` - Uses `supported_chains: ChainName[]`

**Rules:**

1. **Always look up exact names** - Before adding `chainName` or `supported_chains`, search `chains.ts` for the exact `name` value
2. **Names are case-sensitive and exact** - e.g., use `"Zircuit Mainnet"` not `"Zircuit"`, use `"OP Mainnet"` not `"Optimism"`
3. **Run type checking** - Use `npx tsc --noEmit` to verify chain names are valid before committing
4. **Non-EVM chains** - For Starknet and other non-EVM chains, use `NonEVMChainName` type

**Common Mistakes:**

- Using informal names: `"Optimism"` should be `"OP Mainnet"`
- Missing "Mainnet" suffix: `"Zircuit"` should be `"Zircuit Mainnet"`
- Wrong casing: `"zksync Mainnet"` should be `"zkSync Mainnet"`

I would think having this explcitely laid out in the docs/adding-wallets.md file would be best to avoid repeating ourselves in multiple places (e.g., if anything changes, harder to maintain the instructions)

@minimalsm Would you agree? Definitely not picky which we keep, but within this file it seems best to only keep one of these


4. **Check platform flags carefully** - Don't confuse browser extensions with mobile apps:
- Browser extension = `chromium: true` and/or `firefox: true`
- Mobile app = `ios: true` and/or `android: true`

5. **Run build verification** - Always run `pnpm build` to catch TypeScript errors before committing
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pnpm build may be a bulky ask given the weight of our repo:

npx tsc --noEmit

This should be funcitonally equivalent, and only takes a couple seconds to run

Suggested change
5. **Run build verification** - Always run `pnpm build` to catch TypeScript errors before committing
5. **Run TypeScript verification** - Always run `npx tsc --noEmit` to catch TypeScript errors before committing

298 changes: 298 additions & 0 deletions docs/adding-wallets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,298 @@
# Adding Wallets to ethereum.org

This guide provides implementation instructions for adding or updating wallet listings on ethereum.org. It is designed for both human contributors and AI agents implementing wallet changes.

## Overview

Wallet listings on ethereum.org consist of two components:
1. **Wallet image** - A PNG logo file in `public/images/wallets/`
2. **Wallet data** - A TypeScript object in `src/data/wallets/wallet-data.ts`

Both components are **required** for a wallet to display correctly.

## Prerequisites

Before implementing a wallet addition:
- Verify the wallet meets [listing criteria](https://ethereum.org/contributing/adding-wallets/)
- Ensure you have all required information from the wallet suggestion issue
- Confirm you have a high-quality logo image

## Step 1: Add the Wallet Image

### Image Requirements

| Requirement | Specification |
|-------------|---------------|
| Format | PNG (strongly preferred) or SVG |
| Background | Transparent |
| Dimensions | Square aspect ratio, minimum 128x128px |
| File size | Under 150KB recommended |
| Quality | Clear, crisp logo without artifacts |

### File Naming Convention

- Use lowercase
- No spaces or special characters
- Match the wallet name (simplified)
- Examples: `metamask.png`, `trustwallet.png`, `rainbow.png`

### File Location

Place the image at:
```
public/images/wallets/{wallet-name}.png
```

### Obtaining the Image

The image should be provided in the wallet suggestion issue (attached or linked). If not available:
1. Check the wallet's official website or press kit
2. Request the image from the wallet team via the issue
3. **Never** use placeholder images or screenshots

## Step 2: Add Wallet Data

### Import the Image

Add an import statement at the top of `src/data/wallets/wallet-data.ts`:

```typescript
import WalletNameImage from "@/public/images/wallets/walletname.png"
```

Import statements are ordered alphabetically by variable name.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we emphasize that this is required for build to pass? npx tsx --noEmit will catch this, so maybe not a big deal


### Add the Wallet Entry

Add a new object to the `walletsData` array. Here's a complete template:

```typescript
{
last_updated: "YYYY-MM-DD", // Today's date
name: "Wallet Name",
image: WalletNameImage, // The imported image
twBackgroundColor: "bg-[#HEXCODE]", // Brand color from issue
twGradiantBrandColor: "from-[#HEXCODE]", // Same as background
url: "https://wallet-website.com/",
active_development_team: true,
languages_supported: ["en", "es", "zh"], // ISO 639-1 codes
twitter: "https://x.com/wallethandle",
discord: "https://discord.gg/invite",
reddit: "", // Empty string if not available
telegram: "",
ios: true, // true/false for platform support
android: true,
linux: false,
windows: false,
macOS: false,
firefox: false,
chromium: false,
hardware: false,
open_source: true,
repo_url: "https://github.com/org/repo",
non_custodial: true,
security_audit: [
"https://audit-url-1.com",
"https://audit-url-2.com",
],
scam_protection: false,
hardware_support: false,
rpc_importing: false,
nft_support: true,
connect_to_dapps: true,
staking: false,
swaps: true,
layer_2: true,
gas_fee_customization: true,
ens_support: true,
erc_20_support: true,
buy_crypto: false,
withdraw_crypto: false,
multisig: false,
social_recovery: false,
onboard_documentation: "https://docs.wallet.com/",
documentation: "https://docs.wallet.com/developers",
supported_chains: ["Ethereum Mainnet", "Base", "Arbitrum One"], // Optional
},
```

### Supported Chains

The optional `supported_chains` field must use **exact chain names** from `src/data/chains.ts`. Common examples:
- `"Ethereum Mainnet"` (chainId: 1)
- `"OP Mainnet"` (chainId: 10) - Note: NOT "Optimism"
- `"Arbitrum One"` (chainId: 42161)
- `"Base"` (chainId: 8453)
- `"Polygon zkEVM"` (chainId: 1101)
- `"zkSync Mainnet"` (chainId: 324)
- `"Linea"` (chainId: 59144)
- `"Scroll"` (chainId: 534352)

Always verify chain names against `src/data/chains.ts` before adding.

### Languages Supported

Use ISO 639-1 two-letter codes. Common codes:
- `en` - English
- `zh` - Chinese
- `es` - Spanish
- `ko` - Korean
- `ja` - Japanese
- `fr` - French
- `de` - German
- `pt` - Portuguese
- `tr` - Turkish
- `ru` - Russian

## Step 3: Verify the Implementation

### TypeScript Validation

Run the build to check for type errors:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, would recommend npx tsc --noEmit

Suggested change
Run the build to check for type errors:
Run the TypeScript analyzer to check for type errors:

```bash
pnpm build
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pnpm build
npx tsc --noEmit

```

Common errors:
- Missing image file (import fails)
- Incorrect field names or types
- Missing required fields

### Visual Verification

1. Start the dev server: `pnpm dev`
2. Navigate to the wallets page
3. Verify:
- Wallet appears in the list
- Logo displays correctly
- Background color matches brand
- All feature flags are accurate

## Common Mistakes to Avoid

### 1. Missing Image
**Wrong**: Adding wallet data without the image file
```typescript
image: WalletNameImage, // Will fail if image file doesn't exist
```
**Fix**: Always add the image file first

### 2. Incorrect Chain Names
**Wrong**: Using unofficial names
```typescript
supported_chains: ["Optimism", "Polygon", "Gnosis"],
```
**Correct**: Using exact names from chains.ts
```typescript
supported_chains: ["OP Mainnet", "Polygon zkEVM", "Gnosis"],
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol.. assuming the LLM wrote this, it didn't even check chains.ts for proper examples:

Suggested change
supported_chains: ["OP Mainnet", "Polygon zkEVM", "Gnosis"],
supported_chains: ["OP Mainnet", "Polygon zkEVM"],

```

### 3. Wrong Platform Flags
**Wrong**: Marking browser extension as mobile app
```typescript
ios: true, // Browser extension is NOT an iOS app
chromium: true,
```
**Correct**: Set only accurate platform flags
```typescript
ios: false,
chromium: true, // Chromium-based browser extension
```

### 4. Empty vs Missing Fields
- Use empty string `""` for optional text fields without values
- Use empty array `[]` for optional array fields
- Never omit required fields

## Updating an Existing Wallet

When updating a wallet (e.g., rebrand):

1. **Update the image if changed**:
- Add new image file with new name
- Update the import statement
- Remove old image file if name changed

2. **Update wallet data**:
- Change `name` field
- Update `last_updated` to today's date
- Update URLs, social links, features as needed
- Update `image` reference if filename changed

3. **Clean up**:
- Remove old image file if replaced
- Remove old import statement

## Example: Complete Wallet Addition

Here's a real example based on actual wallet data:

### 1. Add image
Save logo to: `public/images/wallets/rainbow.png`

### 2. Add import
```typescript
import RainbowImage from "@/public/images/wallets/rainbow.png"
```

### 3. Add data entry
```typescript
{
last_updated: "2024-10-30",
name: "Rainbow",
image: RainbowImage,
twBackgroundColor: "bg-[#001E59]",
twGradiantBrandColor: "from-[#001E59]",
url: "https://rainbow.me/",
active_development_team: true,
languages_supported: ["en", "zh", "es", "fr", "de", "ja", "ko", "pt", "ru"],
twitter: "https://x.com/rainbow",
discord: "https://discord.gg/rainbow",
reddit: "",
telegram: "",
ios: true,
android: true,
linux: false,
windows: false,
macOS: false,
firefox: false,
chromium: true,
hardware: false,
open_source: true,
repo_url: "https://github.com/rainbow-me/rainbow",
non_custodial: true,
security_audit: [],
scam_protection: true,
hardware_support: true,
rpc_importing: true,
nft_support: true,
connect_to_dapps: true,
staking: false,
swaps: true,
layer_2: true,
gas_fee_customization: true,
ens_support: true,
erc_20_support: true,
buy_crypto: true,
withdraw_crypto: false,
multisig: false,
social_recovery: false,
onboard_documentation: "https://learn.rainbow.me/",
documentation: "",
supported_chains: ["Ethereum Mainnet", "Base", "Arbitrum One", "OP Mainnet"],
},
```

## Checklist

Before submitting a PR:

- [ ] Image file exists at `public/images/wallets/{name}.png`
- [ ] Image is PNG format with transparent background
- [ ] Import statement added and alphabetically ordered
- [ ] All required fields populated in wallet data object
- [ ] `last_updated` set to today's date
- [ ] Chain names match exactly with `src/data/chains.ts`
- [ ] Platform flags accurately reflect wallet availability
- [ ] `pnpm build` succeeds without errors
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to above, in particular for LLM jobs, asking it to run pnpm build will add bloat. npx tsc --noEmit should suffice for the vast majority of issues we encounter. If that passes, I'd say Netlify can then do the actual building part.

Suggested change
- [ ] `pnpm build` succeeds without errors
- [ ] `npx tsc --noEmit` succeeds without errors

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps an optional step for any other contributors to actually run a full pnpm build and preview to ensure completion and accuracy.

- [ ] Visual verification in dev server confirms correct display