Skip to content

Commit 1594802

Browse files
committed
[ICONS] 🔧 cursor skill to add a crypto icon
1 parent 4ed474c commit 1594802

8 files changed

Lines changed: 574 additions & 345 deletions

File tree

.cursor/commands/add-icon.md

Lines changed: 340 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
---
2+
name: add-icon
3+
description: Add a new cryptocurrency icon to the project with proper compression and mapping
4+
---
5+
6+
# Add Icon
7+
8+
Guide user through adding a new cryptocurrency icon following the project's README.md guidelines.
9+
10+
## Prompt Variables
11+
12+
$TICKER
13+
14+
> The token ticker (will be used as PNG filename in UPPERCASE)
15+
> Examples: USDC, BTC, PEPE, RSETH
16+
17+
$FETCH_LEDGER_IDS
18+
19+
> Should ledger IDs be fetched from Coinradar? yes | no
20+
>
21+
> - `yes`: Automatically fetch ledger IDs from Coinradar API
22+
> - `no`: User will provide ledger IDs manually or they already exist in \_record.json
23+
24+
$SKIP_COMPRESSION
25+
26+
> Skip the compression step? yes | no
27+
>
28+
> - `yes`: File is already compressed and in assets/ folder
29+
> - `no`: File needs to be compressed from compress/ folder (default)
30+
31+
$RUN_GENERATE_INDEX
32+
33+
> Run pnpm generate:index after updating? yes | no
34+
>
35+
> - `yes`: Automatically generate index.json (default)
36+
> - `no`: Skip index generation (user will run manually)
37+
38+
## Instructions
39+
40+
**⚠️ Important:** All file paths in these instructions are relative to the workspace root. When running commands or checking files, ensure you're using paths from the workspace root or absolute paths to avoid confusion with relative paths.
41+
42+
### Step 1: Validate Prerequisites
43+
44+
According to README.md, the icon must meet these requirements:
45+
46+
**PNG File Requirements:**
47+
48+
- Size: 144x144 pixels
49+
- Format: PNG
50+
- Background: Required (no transparent background)
51+
- Max size after compression: ≤50 KB (aim for smaller, 41 KB is already large)
52+
- Naming: Use ticker or recognizable name (e.g., PEPE.png, USDC.png)
53+
54+
Inform the user of these requirements.
55+
56+
### Step 2: Fetch Ledger IDs (if requested)
57+
58+
If $FETCH_LEDGER_IDS is "yes":
59+
60+
1. Fetch top 1000 currencies from Coinradar:
61+
62+
```
63+
https://api.coinradar.ledger.com/v1/live/currencies?limit=1000&offset=0
64+
```
65+
66+
2. Find the currency matching $TICKER (case-insensitive)
67+
68+
3. If found:
69+
- Extract `coinradarId`
70+
- Fetch detailed data:
71+
```
72+
https://api.coinradar.ledger.com/v1/live/currency-nested/{coinradarId}
73+
```
74+
- Extract all `ledgerId` values where `ledgerId !== null`
75+
- Store for later use
76+
77+
4. If not found:
78+
- Log warning: "Token not found in Coinradar API"
79+
- Continue without ledger IDs (user can add manually)
80+
81+
If $FETCH_LEDGER_IDS is "no":
82+
83+
- Skip this step
84+
- Check if $TICKER already exists in `_record.json`
85+
86+
### Step 3: Prepare PNG File
87+
88+
The filename will be: `{$TICKER}.png` (uppercase)
89+
90+
**If $SKIP_COMPRESSION is "no" (default):**
91+
92+
1. Instruct user:
93+
94+
```
95+
Please add your PNG file to the compress/ folder:
96+
compress/{$TICKER}.png
97+
98+
Requirements:
99+
- 144x144 pixels
100+
- PNG format with background
101+
- Named: {$TICKER}.png
102+
103+
Type 'ready' when the file is in place.
104+
```
105+
106+
2. Wait for user confirmation
107+
108+
3. Verify file exists at `compress/{$TICKER}.png` (use absolute path from workspace root)
109+
110+
4. Run compression:
111+
112+
```bash
113+
cd lib && pnpm compress
114+
```
115+
116+
**IMPORTANT:** The compression script outputs to `compress/out/{$TICKER}.png`, not `compress/`!
117+
118+
5. Verify compressed file exists:
119+
120+
```bash
121+
ls -lh compress/out/{$TICKER}.png
122+
```
123+
124+
6. Move compressed file to assets:
125+
126+
```bash
127+
mv compress/out/{$TICKER}.png assets/{$TICKER}.png
128+
```
129+
130+
**Note:** Always use paths from the workspace root or absolute paths to avoid confusion.
131+
132+
7. Clean up source files:
133+
```bash
134+
rm compress/{$TICKER}.png
135+
rmdir compress/out 2>/dev/null || true
136+
```
137+
138+
**If $SKIP_COMPRESSION is "yes":**
139+
140+
1. Verify file exists at `assets/{$TICKER}.png`
141+
2. If not found, error and exit
142+
143+
### Step 5: Verify File Size
144+
145+
Check the file size of `assets/{$TICKER}.png`:
146+
147+
```bash
148+
ls -lh assets/{$TICKER}.png
149+
```
150+
151+
**Note:** If the file is not found, ensure you're using the path from the workspace root, or use the absolute path to avoid confusion.
152+
153+
**Validation:**
154+
155+
- If ≤50 KB: ✅ "File size: {size} KB (within limit)"
156+
- If >50 KB: ⚠️ "Warning: File exceeds 50 KB limit ({size} KB). Consider optimizing further."
157+
158+
### Step 6: Update \_record.json
159+
160+
1. Read `assets/_record.json`
161+
162+
2. Convert $TICKER to UPPERCASE
163+
164+
3. Check if entry exists:
165+
166+
**If exists:**
167+
- Get existing IDs: `record[$TICKER].ids`
168+
- If we have new ledger IDs from Step 2:
169+
- Merge: `[...existingIds, ...newIds]`
170+
- Remove duplicates
171+
- Sort alphabetically
172+
- Update: `record[$TICKER].ids = mergedIds`
173+
- Log: "Updated existing entry for {$TICKER}"
174+
175+
**If not exists:**
176+
- Create new entry: `record[$TICKER] = { ids: ledgerIds }`
177+
- Ensure alphabetical insertion in the JSON object
178+
- Log: "Created new entry for {$TICKER}"
179+
180+
4. Write updated record to `assets/_record.json`
181+
- Maintain alphabetical order of keys
182+
- Use 2-space indentation
183+
- Add newline at end of file
184+
185+
### Step 7: Generate Index
186+
187+
If $RUN_GENERATE_INDEX is "yes" (default):
188+
189+
```bash
190+
cd lib && pnpm generate:index
191+
```
192+
193+
This updates `assets/index.json` from `_record.json`.
194+
195+
If "no":
196+
197+
- Skip and remind user: "Remember to run: cd lib && pnpm generate:index"
198+
199+
### Step 8: Output Summary
200+
201+
Display completion message:
202+
203+
```
204+
✅ Icon for {$TICKER} added successfully!
205+
206+
Files updated:
207+
✓ assets/{$TICKER}.png ({size} KB)
208+
✓ assets/_record.json
209+
✓ assets/index.json
210+
211+
Ledger IDs: {count} total
212+
```
213+
214+
### Step 9: Suggest Next Steps
215+
216+
Suggest running verification:
217+
218+
```
219+
Next steps:
220+
- Verify icon: node scripts/verify-icons.js
221+
- View icon: open assets/{$TICKER}.png
222+
```
223+
224+
## Example Execution
225+
226+
**Variables:**
227+
228+
- $TICKER: "PEPE"
229+
- $FETCH_LEDGER_IDS: "yes"
230+
- $SKIP_COMPRESSION: "no"
231+
- $RUN_GENERATE_INDEX: "yes"
232+
233+
**Expected flow:**
234+
235+
```
236+
🎨 Adding icon for PEPE...
237+
238+
Step 1: Fetching ledger IDs from Coinradar...
239+
✓ Found: Pepe (PEPE)
240+
✓ Fetched 3 ledger IDs
241+
242+
Step 2: Preparing PNG file...
243+
📝 Please add your PNG file to: compress/PEPE.png
244+
245+
Requirements:
246+
- 144x144 pixels
247+
- PNG format with background
248+
- Named: PEPE.png
249+
250+
Type 'ready' when the file is in place.
251+
252+
[User types: ready]
253+
254+
✓ File found at compress/PEPE.png
255+
🔄 Running compression...
256+
✓ Compression complete (output: compress/out/PEPE.png)
257+
✓ Verified compressed file
258+
✓ Moved to assets/PEPE.png
259+
260+
Step 3: Verifying file size...
261+
✓ File size: 28.4 KB (within 50 KB limit)
262+
263+
Step 4: Updating _record.json...
264+
✓ Created new entry for PEPE
265+
✓ Added 3 ledger IDs
266+
267+
Step 5: Generating index...
268+
🔄 Running pnpm generate:index...
269+
✓ Index generated successfully
270+
271+
✅ Icon for PEPE added successfully!
272+
273+
Files updated:
274+
✓ assets/PEPE.png (28.4 KB)
275+
✓ assets/_record.json
276+
✓ assets/index.json
277+
278+
Ledger IDs: 3 total
279+
- arbitrum/erc20/pepe
280+
- ethereum/erc20/pepe
281+
- linea/erc20/pepe
282+
283+
Next steps:
284+
- Verify icon: node scripts/verify-icons.js
285+
- View icon: open assets/PEPE.png
286+
```
287+
288+
## Error Handling
289+
290+
**File not found after user confirmation:**
291+
292+
```
293+
❌ Error: File not found at compress/PEPE.png
294+
Please ensure the file is in place and try again.
295+
```
296+
297+
**Compression failed:**
298+
299+
```
300+
❌ Error: Compression failed
301+
Reason: {error message}
302+
You may need to optimize the source file manually.
303+
```
304+
305+
**File too large:**
306+
307+
```
308+
⚠️ Warning: File size is 68.2 KB (exceeds 50 KB limit)
309+
The icon was added, but consider re-optimizing the source file.
310+
Aim for <50 KB (ideally much smaller).
311+
```
312+
313+
**Token not found in Coinradar:**
314+
315+
```
316+
⚠️ Warning: PEPE not found in Coinradar API
317+
Icon will be added without ledger IDs.
318+
You can add them manually to _record.json later.
319+
```
320+
321+
**generate:index failed:**
322+
323+
```
324+
❌ Error: Failed to generate index
325+
Reason: {error message}
326+
You can run it manually: cd lib && pnpm generate:index
327+
```
328+
329+
## Notes
330+
331+
- PNG filename becomes the key in `_record.json` (without .png extension)
332+
- All tickers are converted to UPPERCASE for consistency
333+
- Compression is done via `pnpm compress` which:
334+
- Reads from `compress/` folder
335+
- Outputs compressed files to `compress/out/` folder
336+
- Files must then be moved from `compress/out/` to `assets/`
337+
- The verification script (`scripts/verify-icons.js`) validates file sizes and ledger IDs
338+
- Storybook shows production icons only, so new icons won't appear in storybook branches
339+
- If design/UX help is needed for the icon, user should contact the design or WXP team
340+
- Always use paths from workspace root or absolute paths when verifying file locations

0 commit comments

Comments
 (0)