Initialized token Lists#1
Conversation
WalkthroughAdds a new CLI script to fetch and generate per-chain token lists from CoinGecko and writes JSON outputs. Introduces three new token list JSON files, a comprehensive README rewrite, a pull request template, and a minor LICENSE punctuation tweak. No exported APIs changed; all additions are data, docs, and a standalone script. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor U as User
participant C as CLI Script (script.js)
participant R as RateLimiter
participant G as CoinGecko API
participant F as File System
U->>C: Run script and enter platform name
C->>R: Request permission to fetch list
R-->>C: Permit within 25 req/min
C->>G: GET coin list
G-->>C: Coin list with platforms
C->>C: Filter coins by platform and prepare batches
loop For each batch
C->>R: Request permission to fetch market data
R-->>C: Permit / delay if needed
C->>G: GET market data (ids, vs_currency=usd)
G-->>C: Market data
C->>C: Merge with contract addresses, apply cap threshold
end
C->>F: Write {platform}-tokens.json
C-->>U: Report results and exit
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~18 minutes Poem
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 Checkov (3.2.334)cardano's-milkomeda-tokens.json/bin/bash: -c: line 1: unexpected EOF while looking for matching `'' 🔧 Biome (2.1.2)cardano's-milkomeda-tokens.json/bin/bash: -c: line 1: unexpected EOF while looking for matching `'' 🔧 ast-grep (0.38.6)cardano's-milkomeda-tokens.json/bin/bash: -c: line 1: unexpected EOF while looking for matching `'' 🔧 Gitleaks (8.27.2)cardano's-milkomeda-tokens.json/bin/bash: -c: line 1: unexpected EOF while looking for matching `'' ✨ Finishing Touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 14
🧹 Nitpick comments (7)
milkomeda-cardano-tokens.json (1)
66-71: Replace placeholder image with a valid URL or remove the field."image": "missing_large.png" will break consumers expecting a resolvable URL.
Apply one of:
- Provide a valid HTTPS image URL hosted on a stable CDN.
- If no image is available, consider omitting the "image" field.
Example diff once a URL is ready:
- "image": "missing_large.png", + "image": "https://coin-images.coingecko.com/coins/images/XXXX/large/busd.png?YYYY",ethereum-classic-tokens.json (1)
45-49: Typo: “Morphro-Aave” → “Morpho-Aave”.Correct the name to match the known project.
- "name": "Morphro-Aave Wrapped BTC", + "name": "Morpho-Aave Wrapped BTC",polygon-pos-tokens.json (1)
1-2241: Add CI validation to keep lists consistent.Given the list size, add a simple CI step to enforce schema, unique ids/symbols, and valid addresses.
I can add a GitHub Action with jq checks similar to the script I shared; want me to open a PR with it?
README.md (3)
2-2: Use id attribute instead of obsolete name on the anchor.HTML name attribute on div is obsolete; switch to id for reliability.
-<div name="readme-top"></div> +<div id="readme-top"></div>
118-121: Add language for fenced code block (markdownlint).Specify a language to satisfy MD040.
-``` +```text Add <TOKEN_NAME> (<TOKEN_SYMBOL>) to <BLOCKCHAIN> list--- `102-112`: **Clarify schema ordering and enforce with tooling.** You ask contributors to sort by symbol. Consider adding a pre-commit script or CI to enforce alphabetical order automatically to avoid drift. I can provide a small Node/jq script to sort entries by .symbol case-insensitively and a GitHub Action to run it. Want me to include that? </blockquote></details> <details> <summary>script.js (1)</summary><blockquote> `86-91`: **Extract batch size to a constant for clarity** Minor readability tweak and single source of truth for the batch size. ```diff - // STEP 2: Break IDs into batches (CoinGecko limit ~250 per request) - const batches = []; - for (let i = 0; i < chainTokens.length; i += 200) { - batches.push(chainTokens.slice(i, i + 200)); - } + // STEP 2: Break IDs into batches (CoinGecko limit ~250 per request) + const BATCH_SIZE = 200; + const batches = []; + for (let i = 0; i < chainTokens.length; i += BATCH_SIZE) { + batches.push(chainTokens.slice(i, i + BATCH_SIZE)); + }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
LICENSE(1 hunks)README.md(1 hunks)ethereum-classic-tokens.json(1 hunks)milkomeda-cardano-tokens.json(1 hunks)polygon-pos-tokens.json(1 hunks)script.js(1 hunks)
🧰 Additional context used
🪛 markdownlint-cli2 (0.17.2)
README.md
81-81: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
118-118: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🔇 Additional comments (5)
LICENSE (1)
674-674: LGTM: Non-functional punctuation tweak only.License terms remain unchanged; no impact on code or distribution. Safe to merge.
polygon-pos-tokens.json (2)
1473-1478: Potential placeholder/vanity address: ends with 99999999."0x38f9…99999999" for Nya looks suspect. Please verify from an official source.
1018-1023: Verify unusual contract address for Good Game US Dollar
The token’scontract_addressbegins with0xffffff…, which is atypical. Please confirm against an authoritative source (e.g. Polygonscan listing or the project’s official website) that this is the correct ERC-20 address on Polygon.• File:
polygon-pos-tokens.json(around lines 1018–1023)
• Field:"contract_address": "0xffffff9936bd58a008855b0812b44d2c8dffe2aa"script.js (2)
159-163: Good: readline is closed in a finally blockEnsures the TTY is cleanly released on all paths, including errors.
1-4: Confirm ES module configurationI didn’t find a
package.jsonwith"type": "module"nor any.mjsentrypoint in the repo, and you’re using ESM imports (withnode-fetch@3being ESM-only). Node.js will throw aSyntaxErrorunless it knows to treat your files as ES modules. Please ensure one of the following:
- Add or update a
package.jsonat the repository root with{ "type": "module" }- Rename
script.jstoscript.mjs- Or revert to CommonJS syntax (use
require()/module.exportsinstead ofimport/export)
| "id": "wetc-hebeswap", | ||
| "symbol": "wetc", | ||
| "name": "Wrapped ETC", | ||
| "image": "https://coin-images.coingecko.com/coins/images/27126/large/1321.png?1696526178", | ||
| "contract_address": "0x82a618305706b14e7bcf2592d4b9324a366b6dad" | ||
| }, |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Disambiguate duplicate “Wrapped ETC” entries.
Two entries named "Wrapped ETC" will confuse consumers. Clarify the source in the name.
- "name": "Wrapped ETC",
+ "name": "Wrapped ETC (HebeSwap)",📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "id": "wetc-hebeswap", | |
| "symbol": "wetc", | |
| "name": "Wrapped ETC", | |
| "image": "https://coin-images.coingecko.com/coins/images/27126/large/1321.png?1696526178", | |
| "contract_address": "0x82a618305706b14e7bcf2592d4b9324a366b6dad" | |
| }, | |
| "id": "wetc-hebeswap", | |
| "symbol": "wetc", | |
| - "name": "Wrapped ETC", | |
| + "name": "Wrapped ETC (HebeSwap)", | |
| "image": "https://coin-images.coingecko.com/coins/images/27126/large/1321.png?1696526178", | |
| "contract_address": "0x82a618305706b14e7bcf2592d4b9324a366b6dad" | |
| }, |
🤖 Prompt for AI Agents
In ethereum-classic-tokens.json around lines 17 to 22, the "Wrapped ETC" entry
is ambiguous because there are duplicate token names; update the "name" field to
include the source (e.g., "Wrapped ETC (Hebeswap)") to disambiguate for
consumers, keep the "symbol" unchanged, and if there are any id/name collisions
elsewhere also make the "id" unique (for example keep "wetc-hebeswap" or update
it to match the new name pattern); ensure the change is applied consistently
wherever this token is referenced.
| "id": "wrapped-ether", | ||
| "symbol": "wetc", | ||
| "name": "Wrapped ETC", | ||
| "image": "https://coin-images.coingecko.com/coins/images/26639/large/wrapped-ether.png?1726646462", | ||
| "contract_address": "0x1953cab0e5bfa6d4a9bad6e05fd46c1cc6527a5a" | ||
| }, |
There was a problem hiding this comment.
Incorrect CoinGecko id used for Wrapped ETC.
"id": "wrapped-ether" points to WETH, not WETC. This is a data mismatch and will cause downstream consumers to pull the wrong metadata.
Apply this fix (adjust id; verify image URL is for WETC on ETC, not WETH):
- "id": "wrapped-ether",
+ "id": "wrapped-etc",
"symbol": "wetc",
"name": "Wrapped ETC",
- "image": "https://coin-images.coingecko.com/coins/images/26639/large/wrapped-ether.png?1726646462",
+ "image": "https://coin-images.coingecko.com/coins/images/27126/large/1321.png?1696526178",
"contract_address": "0x1953cab0e5bfa6d4a9bad6e05fd46c1cc6527a5a"If this second WETC is a different wrapper implementation, consider disambiguating the name, e.g., "Wrapped ETC (XYZ)".
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "id": "wrapped-ether", | |
| "symbol": "wetc", | |
| "name": "Wrapped ETC", | |
| "image": "https://coin-images.coingecko.com/coins/images/26639/large/wrapped-ether.png?1726646462", | |
| "contract_address": "0x1953cab0e5bfa6d4a9bad6e05fd46c1cc6527a5a" | |
| }, | |
| "id": "wrapped-etc", | |
| "symbol": "wetc", | |
| "name": "Wrapped ETC", | |
| "image": "https://coin-images.coingecko.com/coins/images/27126/large/1321.png?1696526178", | |
| "contract_address": "0x1953cab0e5bfa6d4a9bad6e05fd46c1cc6527a5a" | |
| }, |
🤖 Prompt for AI Agents
In ethereum-classic-tokens.json around lines 24 to 29, the "id" value
"wrapped-ether" is wrong (it's WETH); change the id to the correct CoinGecko id
for Wrapped ETC (e.g., "wrapped-etc" or the exact CoinGecko slug for this
token), update/verify the image URL points to the WETC image on CoinGecko (not
WETH), keep the symbol/name/contract_address as-is, and if this is a distinct
wrapper implementation add a disambiguating suffix to the name (e.g., "Wrapped
ETC (XYZ)") so consumers pull the correct metadata.
| [ | ||
| { | ||
| "id": "chainlink", | ||
| "symbol": "link", | ||
| "name": "Chainlink", | ||
| "image": "https://coin-images.coingecko.com/coins/images/877/large/chainlink-new-logo.png?1696502009", | ||
| "contract_address": "0xf390830df829cf22c53c8840554b98eafc5dcbc2" | ||
| }, | ||
| { | ||
| "id": "mimatic", | ||
| "symbol": "mimatic", | ||
| "name": "MAI", | ||
| "image": "https://coin-images.coingecko.com/coins/images/15264/large/mimatic-red.png?1696514916", | ||
| "contract_address": "0xb9c8f0d3254007ee4b98970b94544e473cd610ec" | ||
| }, | ||
| { | ||
| "id": "wrapped-bitcoin-celer", | ||
| "symbol": "cewbtc", | ||
| "name": "Wrapped Bitcoin - Celer", | ||
| "image": "https://coin-images.coingecko.com/coins/images/25013/large/3717.png?1696524164", | ||
| "contract_address": "0x8d50a024b2f5593605d3ce8183ca8969226fcbf8" | ||
| }, | ||
| { | ||
| "id": "occamfi", | ||
| "symbol": "occ", | ||
| "name": "OccamFi", | ||
| "image": "https://coin-images.coingecko.com/coins/images/14801/large/occfi.PNG?1696514470", | ||
| "contract_address": "0x461d52769884ca6235b685ef2040f47d30c94eb5" | ||
| }, | ||
| { | ||
| "id": "milkyswap", | ||
| "symbol": "milky", | ||
| "name": "MilkySwap", | ||
| "image": "https://coin-images.coingecko.com/coins/images/24792/large/milkyswap.jpeg?1696523952", | ||
| "contract_address": "0x063a5e4cd5e15ac66ea47134eb60e6b30a51b2bf" | ||
| }, | ||
| { | ||
| "id": "tether-usd-celer", | ||
| "symbol": "ceusdt", | ||
| "name": "Celer Bridged Tether (Milkomeda)", | ||
| "image": "https://coin-images.coingecko.com/coins/images/24826/large/usdt.png?1696523983", | ||
| "contract_address": "0x3795c36e7d12a8c252a20c5a7b455f7c57b60283" | ||
| }, | ||
| { | ||
| "id": "usd-coin-celer", | ||
| "symbol": "ceusdc", | ||
| "name": "Bridged USD Coin (Celer)", | ||
| "image": "https://coin-images.coingecko.com/coins/images/24823/large/usdc.png?1696523981", | ||
| "contract_address": "0x6a2d262d56735dba19dd70682b39f6be9a931d98" | ||
| }, | ||
| { | ||
| "id": "wrapped-ada", | ||
| "symbol": "wada", | ||
| "name": "Wrapped ADA", | ||
| "image": "https://coin-images.coingecko.com/coins/images/24791/large/ezgif-2-07900fc0ac.jpg?1696523951", | ||
| "contract_address": "0xae83571000af4499798d1e3b0fa0070eb3a3e3f9" | ||
| }, | ||
| { | ||
| "id": "bridged-dai", | ||
| "symbol": "dai", | ||
| "name": "Bridged DAI", | ||
| "image": "https://coin-images.coingecko.com/coins/images/39809/large/dai.png?1724128089", | ||
| "contract_address": "0x639a647fbe20b6c8ac19e48e2de44ea792c62c5c" | ||
| }, | ||
| { | ||
| "id": "bridged-busd", | ||
| "symbol": "busd", | ||
| "name": "Bridged BUSD", | ||
| "image": "missing_large.png", | ||
| "contract_address": "0x218c3c3d49d0e7b37aff0d8bb079de36ae61a4c0" | ||
| }, | ||
| { | ||
| "id": "wrapped-fantom", | ||
| "symbol": "wftm", | ||
| "name": "Wrapped Fantom", | ||
| "image": "https://coin-images.coingecko.com/coins/images/16036/large/Fantom.png?1696515646", | ||
| "contract_address": "0x332730a4f6e03d9c55829435f10360e13cfa41ff" | ||
| }, | ||
| { | ||
| "id": "bridged-wavax", | ||
| "symbol": "wavax", | ||
| "name": "Bridged WAVAX", | ||
| "image": "https://coin-images.coingecko.com/coins/images/53010/large/avax.png?1734991619", | ||
| "contract_address": "0x65e66a61d0a8f1e686c2d6083ad611a10d84d97a" | ||
| }, | ||
| { | ||
| "id": "bridged-usdc", | ||
| "symbol": "usdc", | ||
| "name": "Bridged USDC", | ||
| "image": "https://coin-images.coingecko.com/coins/images/35218/large/USDC_Icon.png?1707908537", | ||
| "contract_address": "0xb44a9b6905af7c801311e8f4e76932ee959c663c" | ||
| }, | ||
| { | ||
| "id": "wrapped-bnb-celer", | ||
| "symbol": "cewbnb", | ||
| "name": "Wrapped BNB - Celer", | ||
| "image": "https://coin-images.coingecko.com/coins/images/25041/large/7192.png?1696524192", | ||
| "contract_address": "0x7f27352d5f83db87a5a3e00f4b07cc2138d8ee52" | ||
| }, | ||
| { | ||
| "id": "bridged-usdt", | ||
| "symbol": "usdt", | ||
| "name": "Bridged USDT", | ||
| "image": "https://coin-images.coingecko.com/coins/images/35001/large/logo.png?1706959346", | ||
| "contract_address": "0x80a16016cc4a2e6a2caca8a4a498b1699ff0f844" | ||
| }, | ||
| { | ||
| "id": "bridged-wbnb", | ||
| "symbol": "wbnb", | ||
| "name": "Bridged WBNB", | ||
| "image": "https://coin-images.coingecko.com/coins/images/53070/large/wrapped_bnb.png?1735264554", | ||
| "contract_address": "0xfbdd194376de19a88118e84e279b977f165d01b8" | ||
| }, | ||
| { | ||
| "id": "wrapped-ether-celer", | ||
| "symbol": "ceweth", | ||
| "name": "Wrapped Ether - Celer", | ||
| "image": "https://coin-images.coingecko.com/coins/images/24827/large/weth.png?1696523984", | ||
| "contract_address": "0x81ecac0d6be0550a00ff064a4f9dd2400585fe9c" | ||
| }, | ||
| { | ||
| "id": "muesliswap-milk", | ||
| "symbol": "milk", | ||
| "name": "MuesliSwap MILK", | ||
| "image": "https://coin-images.coingecko.com/coins/images/24184/large/image_2024-02-16_164443805.png?1708073805", | ||
| "contract_address": "0x386e685b5cbaa7bc06e3dd2eecdc56105076e4fa" | ||
| }, | ||
| { | ||
| "id": "bridged-weth", | ||
| "symbol": "weth", | ||
| "name": "Bridged WETH", | ||
| "image": "https://coin-images.coingecko.com/coins/images/39723/large/WETH.PNG?1723733967", | ||
| "contract_address": "0xe3f5a90f9cb311505cd691a46596599aa1a0ad7d" | ||
| } | ||
| ] No newline at end of file |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Sanity-check symbols, IDs, and address formats across the list.
Before publishing, validate:
- All items have required keys: id, symbol, name, image, contract_address
- contract_address matches ^0x[0-9a-fA-F]{40}$
- No duplicate symbols/ids
I can automate this. Run:
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
files=(milkomeda-cardano-tokens.json ethereum-classic-tokens.json polygon-pos-tokens.json)
for f in "${files[@]}"; do
echo "Validating $f"
# JSON well-formed
jq -e type "$f" >/dev/null
# Required keys and address format
jq -r '
to_entries
| .[] as $i
| select(.value.id | not) | "Missing id at index \($i.key)"
, select(.value.symbol | not) | "Missing symbol at index \($i.key)"
, select(.value.name | not) | "Missing name at index \($i.key)"
, select(.value.image | not) | "Missing image at index \($i.key)"
, select(.value.contract_address | test("^0x[0-9a-fA-F]{40}$") | not)
| "Bad contract_address at index \($i.key): \(.value.contract_address)"
' "$f"
# Duplicates (case-insensitive)
echo "Duplicate ids (case-insensitive):"
jq -r '[.[] | .id | ascii_downcase] | group_by(.) | map(select(length>1) | .[0]) | .[]' "$f"
echo "Duplicate symbols (case-insensitive):"
jq -r '[.[] | .symbol | ascii_downcase] | group_by(.) | map(select(length>1) | .[0]) | .[]' "$f"
doneLength of output: 892
I’ll correct the jq filters and re-validate all three token files:
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
files=(milkomeda-cardano-tokens.json ethereum-classic-tokens.json polygon-pos-tokens.json)
for f in "${files[@]}"; do
echo "=== Validating $f ==="
# Ensure file is valid JSON array
if ! jq -e 'if type=="array" then . else error("Not an array") end' "$f" >/dev/null; then
echo "ERROR: $f is not a JSON array or is malformed" && continue
fi
# Check required keys and address format
jq -r '
to_entries[] |
.key as $idx |
.value as $val |
(if ($val | has("id") | not) then "Missing id at index \($idx)" else empty end),
(if ($val | has("symbol") | not) then "Missing symbol at index \($idx)" else empty end),
(if ($val | has("name") | not) then "Missing name at index \($idx)" else empty end),
(if ($val | has("image") | not) then "Missing image at index \($idx)" else empty end),
(if ((($val.contract_address // "") | test("^0x[0-9A-Fa-f]{40}$")) | not)
then "Bad contract_address at index \($idx): \($val.contract_address)" else empty end)
' "$f"
# Check for duplicate IDs and symbols (case-insensitive)
echo "Duplicate ids (case-insensitive):"
jq -r '[.[] | .id | ascii_downcase] | group_by(.)[] | select(length>1) | .[0]' "$f" || echo " none"
echo "Duplicate symbols (case-insensitive):"
jq -r '[.[] | .symbol | ascii_downcase] | group_by(.)[] | select(length>1) | .[0]' "$f" || echo " none"
echo
doneLength of output: 3884
Token list validation results – fixes required
All three token files have valid JSON structure, required keys, and correctly formatted contract_address values. However, duplicate symbols were detected and must be resolved:
- milkomeda-cardano-tokens.json: ✅ no issues found
- ethereum-classic-tokens.json: duplicate symbol
wetc(case-insensitive) - polygon-pos-tokens.json: duplicate symbols
frax,quick(case-insensitive)
Please remove or rename these duplicates so that each symbol (and id) is unique within its file.
🤖 Prompt for AI Agents
In milkomeda-cardano-tokens.json around lines 1 to 135 the token list is valid
and contains no duplicate symbols or ids; no changes are required in this file —
keep it as-is. For the other reported files (ethereum-classic-tokens.json and
polygon-pos-tokens.json) resolve the duplicates by ensuring each entry has a
unique symbol and id (rename or remove duplicate entries for `wetc` in
ethereum-classic and `frax`/`quick` in polygon-pos), then re-run validation.
| "id": "frax-share", | ||
| "symbol": "frax", | ||
| "name": "Frax (prev. FXS)", | ||
| "image": "https://coin-images.coingecko.com/coins/images/13423/large/frax.png?1745921071", | ||
| "contract_address": "0x1a3acf6d19267e2d3e7f898f42803e90c9219062" | ||
| }, |
There was a problem hiding this comment.
Wrong symbol/name for Frax Share.
This entry uses id "frax-share" but symbol "frax" and name "Frax (prev. FXS)". Frax Share’s ticker is FXS; using "frax" collides with FRAX stablecoin.
Apply:
- "id": "frax-share",
- "symbol": "frax",
- "name": "Frax (prev. FXS)",
+ "id": "frax-share",
+ "symbol": "fxs",
+ "name": "Frax Share",📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "id": "frax-share", | |
| "symbol": "frax", | |
| "name": "Frax (prev. FXS)", | |
| "image": "https://coin-images.coingecko.com/coins/images/13423/large/frax.png?1745921071", | |
| "contract_address": "0x1a3acf6d19267e2d3e7f898f42803e90c9219062" | |
| }, | |
| "id": "frax-share", | |
| "symbol": "fxs", | |
| "name": "Frax Share", | |
| "image": "https://coin-images.coingecko.com/coins/images/13423/large/frax.png?1745921071", | |
| "contract_address": "0x1a3acf6d19267e2d3e7f898f42803e90c9219062" | |
| }, |
🤖 Prompt for AI Agents
In polygon-pos-tokens.json around lines 801-806, the entry currently uses id
"frax-share" but incorrectly sets "symbol": "frax" and "name": "Frax (prev.
FXS)"; update this entry so the symbol is "fxs" and the name clearly reflects
Frax Share (e.g., "Frax Share (FXS)"), leaving the id, image and
contract_address unchanged.
| "id": "polygon-ecosystem-token", | ||
| "symbol": "pol", | ||
| "name": "POL (ex-MATIC)", | ||
| "image": "https://coin-images.coingecko.com/coins/images/32440/large/polygon.png?1698233684", | ||
| "contract_address": "0x0000000000000000000000000000000000001010" | ||
| }, |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
POL entry uses non-ERC20 pseudo address (0x…1010).
0x000…1010 is the native MATIC/POL pseudo-address used by some tooling, not an ERC-20. This will break ERC-20 consumers.
Options:
- Remove this entry until the correct POL ERC-20 contract (on Polygon PoS) is confirmed.
- Or, if the intent is Wrapped MATIC/POL, reference WMATIC’s ERC-20 at 0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270 with correct id/symbol/name.
Would you like me to update this entry or drop it pending confirmation?
🏁 Script executed:
#!/bin/bash
# Check for existing WMATIC entry or references in polygon-pos-tokens.json
rg "0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270" -n polygon-pos-tokens.json
rg -i wmatic -n polygon-pos-tokens.json
# Display lines around the POL entry to confirm context
sed -n '1150,1200p' polygon-pos-tokens.jsonLength of output: 2089
Fix POL entry: replace or remove non-ERC-20 pseudo-address
The polygon-ecosystem-token entry uses the native MATIC pseudo-address (0x000…1010), which isn’t an ERC-20 contract and will break ERC-20 integrations. You have two options:
• Remove the entire polygon-ecosystem-token block (lines 1165–1170 in polygon-pos-tokens.json) since native MATIC isn’t an on-chain ERC-20.
• Or, if you meant to list wrapped MATIC, change it to WMATIC:
{
- "id": "polygon-ecosystem-token",
- "symbol": "pol",
- "name": "POL (ex-MATIC)",
- "contract_address": "0x0000000000000000000000000000000000001010"
+ "id": "wmatic",
+ "symbol": "wmatic",
+ "name": "Wrapped MATIC",
+ "contract_address": "0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270"
},Choose the approach that matches your intent.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "id": "polygon-ecosystem-token", | |
| "symbol": "pol", | |
| "name": "POL (ex-MATIC)", | |
| "image": "https://coin-images.coingecko.com/coins/images/32440/large/polygon.png?1698233684", | |
| "contract_address": "0x0000000000000000000000000000000000001010" | |
| }, | |
| { | |
| "id": "wmatic", | |
| "symbol": "wmatic", | |
| "name": "Wrapped MATIC", | |
| "image": "https://coin-images.coingecko.com/coins/images/32440/large/polygon.png?1698233684", | |
| "contract_address": "0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270" | |
| }, |
🤖 Prompt for AI Agents
In polygon-pos-tokens.json around lines 1165 to 1170 the polygon-ecosystem-token
entry uses the native MATIC pseudo-address (0x000...1010) which is not an ERC-20
contract and will break ERC-20 integrations; either remove this entire block or
replace it with the WMATIC token entry (correct ERC-20 contract address, symbol
"WMATIC", and appropriate name/image) depending on whether you intended to
represent native MATIC or wrapped MATIC—apply the chosen change and ensure the
contract_address is a valid ERC-20 hex address if keeping the token.
| const MARKET_CAP_THRESHOLD = 1_000_000; | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Add a preflight check for required environment variables
Prevent confusing runtime errors by validating COINGECKO_LIST_URL and COINGECKO_MARKET_URL upfront.
const MARKET_CAP_THRESHOLD = 1_000_000;
+// Required env validation
+{
+ const required = ["COINGECKO_LIST_URL", "COINGECKO_MARKET_URL"];
+ const missing = required.filter((k) => !process.env[k]);
+ if (missing.length) {
+ console.error(`❌ Missing required environment variables: ${missing.join(", ")}`);
+ process.exit(1);
+ }
+}
+
rl.question(📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const MARKET_CAP_THRESHOLD = 1_000_000; | |
| const MARKET_CAP_THRESHOLD = 1_000_000; | |
| // Required env validation | |
| { | |
| const required = ["COINGECKO_LIST_URL", "COINGECKO_MARKET_URL"]; | |
| const missing = required.filter((k) => !process.env[k]); | |
| if (missing.length) { | |
| console.error(`❌ Missing required environment variables: ${missing.join(", ")}`); | |
| process.exit(1); | |
| } | |
| } | |
| rl.question( | |
| // ... | |
| ); |
🤖 Prompt for AI Agents
In script.js around lines 62-63, add a preflight check that validates the
presence of the COINGECKO_LIST_URL and COINGECKO_MARKET_URL environment
variables before the code continues; if either is missing, log a clear error
including the missing variable names and abort startup (throw an Error or call
process.exit(1)) so the program fails fast with a helpful message rather than
producing confusing runtime errors later.
| rl.question( | ||
| "Enter chain/platform name (e.g., ethereum, polygon-pos, ethereum-classic): ", | ||
| async (platformName) => { | ||
| try { |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Normalize user input to avoid mismatches and handle empty input
Trim and lowercase the platform to match CoinGecko platform keys, and bail out early when no input is provided.
rl.question(
"Enter chain/platform name (e.g., ethereum, polygon-pos, ethereum-classic): ",
async (platformName) => {
try {
+ platformName = (platformName || "").trim().toLowerCase();
+ if (!platformName) {
+ console.log("❌ No platform name provided.");
+ rl.close();
+ return;
+ }
// STEP 1: Fetch tokens with contract addresses on this chain📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| rl.question( | |
| "Enter chain/platform name (e.g., ethereum, polygon-pos, ethereum-classic): ", | |
| async (platformName) => { | |
| try { | |
| rl.question( | |
| "Enter chain/platform name (e.g., ethereum, polygon-pos, ethereum-classic): ", | |
| async (platformName) => { | |
| try { | |
| platformName = (platformName || "").trim().toLowerCase(); | |
| if (!platformName) { | |
| console.log("❌ No platform name provided."); | |
| rl.close(); | |
| return; | |
| } | |
| // STEP 1: Fetch tokens with contract addresses on this chain |
🤖 Prompt for AI Agents
In script.js around lines 64 to 67, the prompt handler uses raw user input for
the platform name which can cause mismatches with CoinGecko keys and may accept
empty input; trim whitespace and convert the input to lowercase before use, and
if the resulting string is empty return early (close or prompt again) with a
clear message or error to avoid making unnecessary API calls.
| console.log( | ||
| `✅ Found ${chainTokens.length} tokens with contracts on ${platformName}` | ||
| ); | ||
|
|
||
| // STEP 2: Break IDs into batches (CoinGecko limit ~250 per request) |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Avoid O(n^2) lookups when merging; build an id→contract index and handle null market caps
The current chainTokens.find per token is O(n) and repeated across all results. Also, md.market_cap can be null, which unintentionally filters tokens even when the threshold is 0.
Build an index once:
console.log(
`✅ Found ${chainTokens.length} tokens with contracts on ${platformName}`
);
+ // Build id -> contract address index to avoid O(n^2) lookups later
+ const idToContract = new Map(
+ chainTokens.map((t) => [t.id, t.platforms[platformName]])
+ );
+
// STEP 2: Break IDs into batches (CoinGecko limit ~250 per request)Use the index and coalesce market cap:
- // STEP 3: Merge market data with contract addresses and filter by threshold
+ // STEP 3: Merge market data with contract addresses and filter by threshold
for (const md of marketData) {
try {
- const original = chainTokens.find((t) => t.id === md.id);
- if (!original) {
+ const contract = idToContract.get(md.id);
+ if (!contract) {
skippedCount++;
continue;
}
- if (md.market_cap >= currentThreshold) {
+ const marketCap = md.market_cap ?? 0;
+ if (marketCap >= currentThreshold) {
finalList.push({
id: md.id,
symbol: md.symbol,
name: md.name,
image: md.image,
- contract_address: original.platforms[platformName],
+ contract_address: contract,
});
processedCount++;
}
} catch (err) {Also applies to: 116-134
🤖 Prompt for AI Agents
In script.js around lines 82-86 (and similarly 116-134), the code uses
chainTokens.find for each CoinGecko result causing O(n^2) behavior and treats
md.market_cap === null as falsy which can drop tokens when threshold is 0; fix
by creating a one-time map from token id to its contract/token object (e.g.,
const idToToken = new Map(chainTokens.map(t => [t.id, t]))) and replace
per-result .find calls with O(1) lookups via that map, and when reading
md.market_cap coalesce null to 0 (e.g., const marketCap = md.market_cap ?? 0)
before comparing to the threshold so tokens with null market caps are handled
correctly.
| const url = `${process.env.COINGECKO_MARKET_URL}?vs_currency=usd&ids=${ids}&order=market_cap_desc&sparkline=false&x_cg_demo_api_key=${process.env.API_KEY}`; | ||
| try { | ||
| const marketResponse = await fetchWithRetry(url); | ||
| // Add a small delay between batch requests to avoid rate limits |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Don’t send API keys in query strings; prefer headers and add to all requests, not just markets
Placing secrets in URLs leaks them via logs, proxies, and analytics. Prefer the documented header for API keys and ensure both LIST and MARKET endpoints carry it.
I can update fetchWithRetry to accept an options parameter and inject headers consistently. Meanwhile, please confirm the correct header/param name for CoinGecko’s demo/pro keys:
If confirmed to be headers, I’ll provide a compact patch to:
- extend fetchWithRetry(url, retries, baseDelay, options)
- pass { headers: { 'x-cg-demo-api-key': process.env.API_KEY } } (or pro equivalent)
- apply to both COINGECKO_LIST_URL and COINGECKO_MARKET_URL requests.
🌐 Web query:
What header or query parameter should be used to send CoinGecko API keys (demo and pro)? Provide the exact header/param names as per the latest docs.
💡 Result:
To send CoinGecko API keys, the required header or query parameter names differ for demo and pro (paid) plans:
For Demo (Free) API Keys:
- Query parameter:
x_cg_demo_api_key - Header:
x-cg-demo-api-key[2][6][10]
Example usage (query parameter):
https://api.coingecko.com/api/v3/ping?x_cg_demo_api_key=YOUR_API_KEY
Example usage (header):
x-cg-demo-api-key: YOUR_API_KEY
For Pro (Paid) API Keys:
- Query parameter:
x_cg_pro_api_key - Header:
x-cg-pro-api-key[3][6]
Example usage (query parameter):
https://pro-api.coingecko.com/api/v3/ping?x_cg_pro_api_key=YOUR_API_KEY
Example usage (header):
x-cg-pro-api-key: YOUR_API_KEY
- Use demo key format (
x_cg_demo_api_keyorx-cg-demo-api-key) with api.coingecko.com endpoints. - Use pro key format (
x_cg_pro_api_keyorx-cg-pro-api-key) with pro-api.coingecko.com endpoints.
These are the exact names as specified in CoinGecko’s official documentation and guides as of June 2025[2][3][6][10].
Citations:
- 1: https://apipheny.io/coingecko-api/
- 2: https://support.coingecko.com/hc/en-us/articles/21880397454233-User-Guide-How-to-sign-up-for-CoinGecko-Demo-API-and-generate-an-API-key
- 3: https://support.coingecko.com/hc/en-us/articles/4538879945625-API-key-can-I-store-the-key-in-my-headers
- 4: https://www.coingecko.com/learn/get-token-holders
- 5: Feature/Add Coingecko api key support ghostfolio/ghostfolio#2826
- 6: https://mixedanalytics.com/knowledge-base/import-coingecko-data-to-google-sheets/
- 7: https://www.coingecko.com/en/api
- 8: https://docs.coingecko.com/reference/setting-up-your-api-key
- 9: https://huggingface.co/datasets/Zentris/zentris
- 10: https://www.coingecko.com/learn/python-query-coingecko-api
Use headers for CoinGecko API keys on all requests
To prevent leaking secrets via URLs, switch from the x_cg_demo_api_key/x_cg_pro_api_key query param to the documented headers (x-cg-demo-api-key for demo keys, x-cg-pro-api-key for paid keys) and apply this to both LIST and MARKET endpoints.
• Locations to update:
- script.js around lines ~108–111 (MARKET endpoint)
- wherever you call COINGECKO_LIST_URL
• Refactor fetchWithRetry to accept an options object and merge headers:
// before
async function fetchWithRetry(url, retries = 3, baseDelay = 500) { … }
// after
async function fetchWithRetry(
url,
retries = 3,
baseDelay = 500,
options = {}
) {
return fetch(url, { ...options }).then(/* retry logic */);
}• Example diff for the MARKET call:
- const url = `${process.env.COINGECKO_MARKET_URL}?vs_currency=usd&ids=${ids}&order=market_cap_desc&sparkline=false&x_cg_demo_api_key=${process.env.API_KEY}`;
- const marketResponse = await fetchWithRetry(url);
+ const url = `${process.env.COINGECKO_MARKET_URL}?vs_currency=usd&ids=${ids}&order=market_cap_desc&sparkline=false`;
+ const headers = { 'x-cg-demo-api-key': process.env.API_KEY };
+ const marketResponse = await fetchWithRetry(url, undefined, undefined, { headers });Repeat similarly for the LIST endpoint, swapping in x-cg-pro-api-key if using the pro URL.
🤖 Prompt for AI Agents
In script.js around lines 108–111, the MARKET request currently puts the
CoinGecko API key in the query string; update this and any LIST calls to use the
documented headers instead. Remove the x_cg_demo_api_key/x_cg_pro_api_key query
param from the URL and add the appropriate header name (x-cg-demo-api-key for
demo URL, x-cg-pro-api-key for pro URL) to the request. Refactor fetchWithRetry
to accept an options object (e.g., last param) and merge/override headers into
fetch, preserving existing headers; update all calls (MARKET and LIST) to pass {
headers: { 'x-cg-...-api-key': process.env.API_KEY, ...anyExistingHeaders } }
when invoking fetchWithRetry. Ensure URLs no longer contain API key query params
and that retry logic still wraps the fetch call.
| // STEP 4: Save to file | ||
| const fileName = `${platformName}-tokens.json`; | ||
| fs.writeFileSync(fileName, JSON.stringify(finalList, null, 2)); | ||
| } catch (err) { |
There was a problem hiding this comment.
Sanitize the output file name to prevent path traversal or accidental overwrites
User input can inject path separators. Sanitize it before composing the file path.
- // STEP 4: Save to file
- const fileName = `${platformName}-tokens.json`;
+ // STEP 4: Save to file
+ const safeSuffix = platformName
+ .toLowerCase()
+ .replace(/[^a-z0-9-]/g, "-")
+ .replace(/-+/g, "-")
+ .replace(/^-|-$/g, "");
+ const fileName = `${safeSuffix}-tokens.json`;
fs.writeFileSync(fileName, JSON.stringify(finalList, null, 2));📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // STEP 4: Save to file | |
| const fileName = `${platformName}-tokens.json`; | |
| fs.writeFileSync(fileName, JSON.stringify(finalList, null, 2)); | |
| } catch (err) { | |
| // STEP 4: Save to file | |
| const safeSuffix = platformName | |
| .toLowerCase() | |
| .replace(/[^a-z0-9-]/g, "-") | |
| .replace(/-+/g, "-") | |
| .replace(/^-|-$/g, ""); | |
| const fileName = `${safeSuffix}-tokens.json`; | |
| fs.writeFileSync(fileName, JSON.stringify(finalList, null, 2)); |
🤖 Prompt for AI Agents
In script.js around lines 155 to 158, the code builds an output filename using
platformName directly which allows path traversal or accidental overwrites;
sanitize platformName by stripping or replacing any path separators and
restricting to a safe whitelist (e.g., allow only letters, numbers, dashes and
underscores, fallback to a default name if empty), then build the filepath with
path.join to a controlled output directory (create it if missing) and prevent
overwrites by checking for an existing file and appending a timestamp or counter
when needed before calling fs.writeFileSync.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
README.md (1)
81-83: Add a language to fenced code block (markdownlint MD040).The raw URL code block is missing a language tag. Use "text" to satisfy MD040.
-``` +```text https://github.com/StabilityNexus/TokenList/main/<blockchain>-tokens.json</blockquote></details> </blockquote></details> <details> <summary>🧹 Nitpick comments (5)</summary><blockquote> <details> <summary>README.md (5)</summary><blockquote> `118-121`: **Add a language to fenced code block (markdownlint MD040).** The "Title Format" example block lacks a language; use "text" for clarity and to appease the linter. ```diff -``` +```text Add <TOKEN_NAME> (<TOKEN_SYMBOL>) to <BLOCKCHAIN> list--- `2-2`: **Use id instead of name for the anchor.** GitHub-flavored Markdown recognizes id better than name for anchors. ```diff -<div name="readme-top"></div> +<div id="readme-top"></div>
5-7: Inline style attributes are stripped by GitHub; simplify the centered container.GitHub sanitizes style attributes; using align is sufficient. This avoids broken layout assumptions.
-<div align="center" style="display: flex; align-items: center; justify-content: center; gap: 16px;"> +<div align="center"> <img alt="Stability Nexus" src="https://github.com/StabilityNexus/HammerAuctionHouse-WebUI/0744fdc330ae6fe1a295468e1a070b2d02d8344f/public/stability.svg" width="175"> </div>
48-51: Fix spelling and verify branding consistency.
- Use a consistent spelling of “recognized” throughout.
- Confirm whether “The Stable Order” is the intended brand here vs “Stability Nexus.”
-<h1>Tokens recognised by The Stable Order</h1> +<h1>Tokens recognized by The Stable Order</h1>If “Stability Nexus” is the intended public-facing brand for this repo, consider aligning the title accordingly.
79-86: Document a commit-pinned URL for consumers.Pointing to main can change unexpectedly. Offer a pinned-by-commit option for reproducibility.
Token lists can be accessed using the following URL format: -```text +```text https://github.com/StabilityNexus/TokenList/main/<blockchain>-tokens.jsonReplace
<blockchain>with the chain name (e.g., ethereum, polygon-pos, ethereum-classic, etc.)
+
+For reproducible builds, pin to a specific commit:
+
+text +https://github.com/StabilityNexus/TokenList/<commit-sha>/<blockchain>-tokens.json +</blockquote></details> </blockquote></details> <details> <summary>📜 Review details</summary> **Configuration used: CodeRabbit UI** **Review profile: CHILL** **Plan: Pro** <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between 4a7ad1ffd83b7d4c0c8b23abdf31320612759e99 and 43084901c6b8cc32063a7a2c7d949a6f25e4f56a. </details> <details> <summary>📒 Files selected for processing (1)</summary> * `README.md` (1 hunks) </details> <details> <summary>🧰 Additional context used</summary> <details> <summary>🪛 markdownlint-cli2 (0.17.2)</summary> <details> <summary>README.md</summary> 81-81: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 118-118: Fenced code blocks should have a language specified (MD040, fenced-code-language) </details> </details> </details> <details> <summary>🔇 Additional comments (1)</summary><blockquote> <details> <summary>README.md (1)</summary> `55-62`: **README token files verified** All JSON token list files referenced in README.md (lines 55-62) exist in the repo. No updates to the file list are needed. </details> </blockquote></details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
| ## Token Requirements | ||
|
|
||
| <!-- TODO --> | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Replace TODO with minimal Token Requirements to reduce ambiguity.
Provide explicit submission criteria to streamline reviews and reduce back-and-forth.
-## Token Requirements
-
-<!-- TODO -->
+## Token Requirements
+
+- Required fields: `id`, `symbol`, `name`, `contract_address`, `image`
+- Sorting: Add tokens in alphabetical order by `symbol`
+- Contract addresses:
+ - EVM chains: use EIP-55 checksum; no proxy/implementation ambiguity
+ - Non-EVM chains: provide canonical chain-specific address/identifier
+- Symbols: Uppercase ASCII, unique within each chain list
+- Images: HTTPS URLs; SVG or PNG preferred; no data URIs
+- Uniqueness: `id` must be globally unique across all lists (prefer CoinGecko id when applicable)
+- Quality: Token must have an active explorer page; optional website and market cap are welcome
+
+Submissions not meeting the above may be requested to revise before merging.I can draft a more formal JSON Schema if you want validation automation.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ## Token Requirements | |
| <!-- TODO --> | |
| ## Token Requirements | |
| - Required fields: `id`, `symbol`, `name`, `contract_address`, `image` | |
| - Sorting: Add tokens in alphabetical order by `symbol` | |
| - Contract addresses: | |
| - EVM chains: use EIP-55 checksum; no proxy/implementation ambiguity | |
| - Non-EVM chains: provide canonical chain-specific address/identifier | |
| - Symbols: Uppercase ASCII, unique within each chain list | |
| - Images: HTTPS URLs; SVG or PNG preferred; no data URIs | |
| - Uniqueness: `id` must be globally unique across all lists (prefer CoinGecko id when applicable) | |
| - Quality: Token must have an active explorer page; optional website and market cap are welcome | |
| Submissions not meeting the above may be requested to revise before merging. |
🤖 Prompt for AI Agents
In README.md around lines 71 to 74, replace the "TODO" placeholder under "Token
Requirements" with a concise list of minimal submission criteria: specify
required token fields (name, symbol, decimals), required metadata (description,
website URL, optional logo URL), size/format constraints (max lengths, allowed
characters, logo file type/size or URL scheme), and any validation rules (unique
symbol, decimals as integer 0-18). Keep the text short, use bullet-like
comma-separated items or a compact paragraph, and include one sentence about how
to request exceptions or provide the JSON Schema offer mentioned in the review
comment.
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (3)
README.md (3)
84-86: Add a language tag to fenced code block (markdownlint MD040).This also echoes the earlier bot suggestion.
-``` +```text https://github.com/StabilityNexus/TokenList/main/<blockchain>-tokens.json--- `57-63`: **Reorder “Supported Blockchains” as previously requested.** A prior review asked for the order: Ethereum Classic, Milkomeda, Polygon, Binance Smart Chain, Base. Please confirm whether Ethereum should be listed and, if so, where it should appear in the order. Proposed reorder (keeping Ethereum at the top if required), or remove Ethereum if not intended: ```diff -- Ethereum (`ethereum-tokens.json`) -- Ethereum Classic (`ethereum-classic-tokens.json`) -- Cardano's Milkomeda (`cardano's-milkomeda-tokens.json`) -- Polygon PoS (`polygon-pos-tokens.json`) -- Binance Smart Chain (`binance-smart-chain-tokens.json`) -- Base(`base-tokens.json`) +- Ethereum (`ethereum-tokens.json`) +- Ethereum Classic (`ethereum-classic-tokens.json`) +- Cardano's Milkomeda (`cardanos-milkomeda-tokens.json`) +- Polygon PoS (`polygon-pos-tokens.json`) +- Binance Smart Chain (`binance-smart-chain-tokens.json`) +- Base (`base-tokens.json`)Note: I also updated the Milkomeda filename to avoid the apostrophe if you proceed with that rename.
74-76: Replace TODO with minimal Token Requirements.Define what submitters must provide to reduce ambiguity and review cycles.
-## Token Requirements - -<!-- TODO --> +## Token Requirements + +- Required fields: `id`, `symbol`, `name`, `contract_address`, `image` +- Symbols: Uppercase ASCII, unique within each chain list +- Contract addresses: + - EVM chains: EIP-55 checksummed; no proxy/implementation ambiguity + - Non-EVM chains: canonical chain-specific address/identifier +- Images: HTTPS URLs; SVG/PNG preferred; no data URIs/placeholders +- Ordering: Add tokens in alphabetical order by `symbol` +- IDs: Prefer CoinGecko `id` when applicable; must be unique globally +- Quality: Token must have an active explorer page; website optional + +Submissions not meeting the above may be requested to revise before merging.
🧹 Nitpick comments (5)
cardano's-milkomeda-tokens.json (1)
1-135: Enforce consistent symbol casing and sorting policy.Symbols are lowercase here, but consumers often expect uppercase (e.g., "LINK", "WETH"). Also, entries aren’t sorted by symbol. Define the policy in README and align the list to it to minimize churn and ambiguity.
I can provide a script to auto-uppercase symbols and sort entries by symbol if you confirm the desired policy.
README.md (4)
2-2: Use id instead of name for the anchor.The name attribute on div is nonstandard/deprecated for anchors. Use id to define the target.
-<div name="readme-top"></div> +<div id="readme-top"></div>
48-49: Fix spelling consistency: use “recognized” (US) to match body text.Header uses British English (“recognised”) while the paragraph uses US (“recognized”). Pick one; using US aligns with Line 51.
-<h1>Tokens recognised by The Stable Order</h1> +<h1>Tokens recognized by The Stable Order</h1>
62-62: Add missing space before the filename.Minor formatting nit in the Supported Blockchains list.
-- Base(`base-tokens.json`) +- Base (`base-tokens.json`)
120-124: Add a language tag to fenced code block (markdownlint MD040).Applies to the PR title example.
-``` +```text Add <TOKEN_NAME> (<TOKEN_SYMBOL>) to <BLOCKCHAIN> list</blockquote></details> </blockquote></details> <details> <summary>📜 Review details</summary> **Configuration used: CodeRabbit UI** **Review profile: CHILL** **Plan: Pro** <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between 43084901c6b8cc32063a7a2c7d949a6f25e4f56a and b6a05e41b56a56da377547dac215d64bbbb37972. </details> <details> <summary>📒 Files selected for processing (3)</summary> * `.github/pull_request_template.md` (1 hunks) * `README.md` (1 hunks) * `cardano's-milkomeda-tokens.json` (1 hunks) </details> <details> <summary>✅ Files skipped from review due to trivial changes (1)</summary> * .github/pull_request_template.md </details> <details> <summary>🧰 Additional context used</summary> <details> <summary>🪛 markdownlint-cli2 (0.17.2)</summary> <details> <summary>README.md</summary> 84-84: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 121-121: Fenced code blocks should have a language specified (MD040, fenced-code-language) </details> </details> </details> <details> <summary>🔇 Additional comments (2)</summary><blockquote> <details> <summary>cardano's-milkomeda-tokens.json (1)</summary> `1-135`: **Verify CoinGecko IDs and image sources are canonical.** Some ids (e.g., “bridged-dai”, “bridged-wavax”) may not map 1:1 with CoinGecko coins. If the intent is to use CoinGecko ids, please confirm each id exists and the image URLs are stable/CDN-backed. Otherwise, document the id semantics (internal vs external) in README. I can add a validator that cross-checks ids against the CoinGecko API if helpful. </details> <details> <summary>README.md (1)</summary> `72-72`: **Nice addition: clear guidance for supporting new blockchains.** The Discord call-out aligns with prior feedback and helps channel requests. </details> </blockquote></details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
| [ | ||
| { | ||
| "id": "chainlink", | ||
| "symbol": "link", | ||
| "name": "Chainlink", | ||
| "image": "https://coin-images.coingecko.com/coins/images/877/large/chainlink-new-logo.png?1696502009", | ||
| "contract_address": "0xf390830df829cf22c53c8840554b98eafc5dcbc2" | ||
| }, | ||
| { | ||
| "id": "mimatic", | ||
| "symbol": "mimatic", | ||
| "name": "MAI", | ||
| "image": "https://coin-images.coingecko.com/coins/images/15264/large/mimatic-red.png?1696514916", | ||
| "contract_address": "0xb9c8f0d3254007ee4b98970b94544e473cd610ec" | ||
| }, | ||
| { | ||
| "id": "wrapped-bitcoin-celer", | ||
| "symbol": "cewbtc", | ||
| "name": "Wrapped Bitcoin - Celer", | ||
| "image": "https://coin-images.coingecko.com/coins/images/25013/large/3717.png?1696524164", | ||
| "contract_address": "0x8d50a024b2f5593605d3ce8183ca8969226fcbf8" | ||
| }, | ||
| { | ||
| "id": "occamfi", | ||
| "symbol": "occ", | ||
| "name": "OccamFi", | ||
| "image": "https://coin-images.coingecko.com/coins/images/14801/large/occfi.PNG?1696514470", | ||
| "contract_address": "0x461d52769884ca6235b685ef2040f47d30c94eb5" | ||
| }, | ||
| { | ||
| "id": "milkyswap", | ||
| "symbol": "milky", | ||
| "name": "MilkySwap", | ||
| "image": "https://coin-images.coingecko.com/coins/images/24792/large/milkyswap.jpeg?1696523952", | ||
| "contract_address": "0x063a5e4cd5e15ac66ea47134eb60e6b30a51b2bf" | ||
| }, | ||
| { | ||
| "id": "tether-usd-celer", | ||
| "symbol": "ceusdt", | ||
| "name": "Celer Bridged Tether (Milkomeda)", | ||
| "image": "https://coin-images.coingecko.com/coins/images/24826/large/usdt.png?1696523983", | ||
| "contract_address": "0x3795c36e7d12a8c252a20c5a7b455f7c57b60283" | ||
| }, | ||
| { | ||
| "id": "usd-coin-celer", | ||
| "symbol": "ceusdc", | ||
| "name": "Bridged USD Coin (Celer)", | ||
| "image": "https://coin-images.coingecko.com/coins/images/24823/large/usdc.png?1696523981", | ||
| "contract_address": "0x6a2d262d56735dba19dd70682b39f6be9a931d98" | ||
| }, | ||
| { | ||
| "id": "wrapped-ada", | ||
| "symbol": "wada", | ||
| "name": "Wrapped ADA", | ||
| "image": "https://coin-images.coingecko.com/coins/images/24791/large/ezgif-2-07900fc0ac.jpg?1696523951", | ||
| "contract_address": "0xae83571000af4499798d1e3b0fa0070eb3a3e3f9" | ||
| }, | ||
| { | ||
| "id": "bridged-dai", | ||
| "symbol": "dai", | ||
| "name": "Bridged DAI", | ||
| "image": "https://coin-images.coingecko.com/coins/images/39809/large/dai.png?1724128089", | ||
| "contract_address": "0x639a647fbe20b6c8ac19e48e2de44ea792c62c5c" | ||
| }, | ||
| { | ||
| "id": "bridged-busd", | ||
| "symbol": "busd", | ||
| "name": "Bridged BUSD", | ||
| "image": "missing_large.png", | ||
| "contract_address": "0x218c3c3d49d0e7b37aff0d8bb079de36ae61a4c0" | ||
| }, | ||
| { | ||
| "id": "wrapped-fantom", | ||
| "symbol": "wftm", | ||
| "name": "Wrapped Fantom", | ||
| "image": "https://coin-images.coingecko.com/coins/images/16036/large/Fantom.png?1696515646", | ||
| "contract_address": "0x332730a4f6e03d9c55829435f10360e13cfa41ff" | ||
| }, | ||
| { | ||
| "id": "bridged-wavax", | ||
| "symbol": "wavax", | ||
| "name": "Bridged WAVAX", | ||
| "image": "https://coin-images.coingecko.com/coins/images/53010/large/avax.png?1734991619", | ||
| "contract_address": "0x65e66a61d0a8f1e686c2d6083ad611a10d84d97a" | ||
| }, | ||
| { | ||
| "id": "bridged-usdc", | ||
| "symbol": "usdc", | ||
| "name": "Bridged USDC", | ||
| "image": "https://coin-images.coingecko.com/coins/images/35218/large/USDC_Icon.png?1707908537", | ||
| "contract_address": "0xb44a9b6905af7c801311e8f4e76932ee959c663c" | ||
| }, | ||
| { | ||
| "id": "wrapped-bnb-celer", | ||
| "symbol": "cewbnb", | ||
| "name": "Wrapped BNB - Celer", | ||
| "image": "https://coin-images.coingecko.com/coins/images/25041/large/7192.png?1696524192", | ||
| "contract_address": "0x7f27352d5f83db87a5a3e00f4b07cc2138d8ee52" | ||
| }, | ||
| { | ||
| "id": "bridged-usdt", | ||
| "symbol": "usdt", | ||
| "name": "Bridged USDT", | ||
| "image": "https://coin-images.coingecko.com/coins/images/35001/large/logo.png?1706959346", | ||
| "contract_address": "0x80a16016cc4a2e6a2caca8a4a498b1699ff0f844" | ||
| }, | ||
| { | ||
| "id": "bridged-wbnb", | ||
| "symbol": "wbnb", | ||
| "name": "Bridged WBNB", | ||
| "image": "https://coin-images.coingecko.com/coins/images/53070/large/wrapped_bnb.png?1735264554", | ||
| "contract_address": "0xfbdd194376de19a88118e84e279b977f165d01b8" | ||
| }, | ||
| { | ||
| "id": "wrapped-ether-celer", | ||
| "symbol": "ceweth", | ||
| "name": "Wrapped Ether - Celer", | ||
| "image": "https://coin-images.coingecko.com/coins/images/24827/large/weth.png?1696523984", | ||
| "contract_address": "0x81ecac0d6be0550a00ff064a4f9dd2400585fe9c" | ||
| }, | ||
| { | ||
| "id": "muesliswap-milk", | ||
| "symbol": "milk", | ||
| "name": "MuesliSwap MILK", | ||
| "image": "https://coin-images.coingecko.com/coins/images/24184/large/image_2024-02-16_164443805.png?1708073805", | ||
| "contract_address": "0x386e685b5cbaa7bc06e3dd2eecdc56105076e4fa" | ||
| }, | ||
| { | ||
| "id": "bridged-weth", | ||
| "symbol": "weth", | ||
| "name": "Bridged WETH", | ||
| "image": "https://coin-images.coingecko.com/coins/images/39723/large/WETH.PNG?1723733967", | ||
| "contract_address": "0xe3f5a90f9cb311505cd691a46596599aa1a0ad7d" | ||
| } | ||
| ] No newline at end of file |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Avoid apostrophes in filenames to reduce quoting/escaping issues.
The filename includes an apostrophe. This complicates shell usage, raw URL consumption, and some tooling. Recommend renaming to: cardanos-milkomeda-tokens.json and updating references in README accordingly.
As a follow-up, update README references (see suggested diffs in README comments).
🤖 Prompt for AI Agents
In cardano's-milkomeda-tokens.json (lines 1-135): the filename contains an
apostrophe which causes quoting/escaping issues; rename the file to
cardanos-milkomeda-tokens.json and update every reference to it (README links,
script paths, CI config, import/require paths, raw URLs) to the new name; ensure
git tracks the rename (git mv) to preserve history and run any tests/builds that
consume the file to confirm no broken references remain.
💡 Verification agent
🧩 Analysis chain
Normalize contract addresses to EIP-55 checksum (mixed-case) across the list.
Most addresses are all-lowercase. For EVM chains, checksummed casing avoids user error and improves interoperability.
Run this script to detect any non-checksummed addresses and see the recommended checksummed form:
If you’d like, I can generate a patch to update all addresses to checksum form.
🏁 Script executed:
#!/bin/bash
set -euo pipefail
pip -q install eth-utils >/dev/null
python - << 'PY'
import json, sys, re, pathlib
from eth_utils import is_checksum_address, to_checksum_address
def scan(path):
with open(path) as f:
data = json.load(f)
bad = []
for i, t in enumerate(data):
addr = t.get("contract_address","")
if isinstance(addr, str) and addr.startswith("0x") and len(addr)==42:
if not is_checksum_address(addr):
bad.append((i, addr, to_checksum_address(addr)))
return bad
for p in pathlib.Path(".").glob("*-tokens.json"):
issues = scan(p)
if issues:
print(f"\nFile: {p}")
for i, a, c in issues:
print(f" index {i}: {a} -> {c}")
PYLength of output: 2046
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Install eth-utils and a Keccak backend for proper checksum computation
pip -q install eth-utils eth-hash[pycryptodome] >/dev/null
# Scan each *-tokens.json file for non-checksummed addresses
python - << 'PY'
import json
from pathlib import Path
from eth_utils import is_checksum_address, to_checksum_address
for path in Path(".").glob("*-tokens.json"):
data = json.loads(path.read_text())
for idx, token in enumerate(data):
addr = token.get("contract_address", "")
if isinstance(addr, str) and addr.startswith("0x") and len(addr) == 42:
if not is_checksum_address(addr):
print(f"{path}: index {idx}: {addr} -> {to_checksum_address(addr)}")
PYLength of output: 268819
Normalize all contract_address entries to EIP-55 checksum format
Every JSON token list (e.g. *-tokens.json) contains lowercase or non-checksummed addresses. Converting them all to mixed-case checksummed form will improve safety and interoperability.
Files requiring updates:
- base-tokens.json
- binance-smart-chain-tokens.json
- cardano’s-milkomeda-tokens.json
- ethereum-classic-tokens.json
- ethereum-tokens.json
Use the attached script to regenerate each address with to_checksum_address(addr) and commit the patch.
🤖 Prompt for AI Agents
In cardano's-milkomeda-tokens.json around lines 1 to 135, all "contract_address"
values are lowercase/non-checksummed; replace each address with its EIP-55
checksum form (use to_checksum_address(addr) from the provided script) for every
token object, update the JSON values in place preserving spacing/quotes and file
encoding, validate the JSON after changes, and commit the patched file.
| "id": "bridged-busd", | ||
| "symbol": "busd", | ||
| "name": "Bridged BUSD", | ||
| "image": "missing_large.png", | ||
| "contract_address": "0x218c3c3d49d0e7b37aff0d8bb079de36ae61a4c0" | ||
| }, |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Replace placeholder image with a valid HTTPS URL or omit the entry until available.
The image field uses a non-URL placeholder ("missing_large.png"). Downstream consumers will likely fail or show broken images. Provide a resolvable HTTPS URL (preferred) or temporarily remove this token until the asset is available.
If you want, I can help source a canonical BUSD logo URL from your chosen provider (CoinGecko/CDN) and open a follow-up PR.
🏁 Script executed:
#!/bin/bash
set -e
# Find all token entries using the placeholder image
rg '"image": "missing_large.png"' -n
# Find all occurrences of the BUSD symbol to locate its definition(s)
rg '"symbol": "busd"' -nLength of output: 354
🏁 Script executed:
#!/bin/bash
set -e
# Extract the BUSD entry from polygon-pos-tokens.json
echo "polygon-pos-tokens.json (lines 45-60):"
sed -n '45,60p' polygon-pos-tokens.json
echo
# Extract the BUSD entry from ethereum-tokens.json
echo "ethereum-tokens.json (lines 855-875):"
sed -n '855,875p' ethereum-tokens.json
echo
# Extract the BUSD entry from binance-smart-chain-tokens.json
echo "binance-smart-chain-tokens.json (lines 400-420):"
sed -n '400,420p' binance-smart-chain-tokens.jsonLength of output: 2525
Update placeholder image for Bridged BUSD
Please replace the placeholder in cardano’s-milkomeda-tokens.json with the official BUSD logo from CoinGecko (matching your Polygon / BSC entries):
• File: cardano’s-milkomeda-tokens.json
Line ~69
- "image": "missing_large.png",
+ "image": "https://coin-images.coingecko.com/coins/images/31273/large/new_binance-peg-busd.png?1696530096",📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "id": "bridged-busd", | |
| "symbol": "busd", | |
| "name": "Bridged BUSD", | |
| "image": "missing_large.png", | |
| "contract_address": "0x218c3c3d49d0e7b37aff0d8bb079de36ae61a4c0" | |
| }, | |
| "id": "bridged-busd", | |
| "symbol": "busd", | |
| "name": "Bridged BUSD", | |
| "image": "https://coin-images.coingecko.com/coins/images/31273/large/new_binance-peg-busd.png?1696530096", | |
| "contract_address": "0x218c3c3d49d0e7b37aff0d8bb079de36ae61a4c0" | |
| }, |
🤖 Prompt for AI Agents
In cardano’s-milkomeda-tokens.json around lines 66–71, the Bridged BUSD entry
uses a placeholder image ("missing_large.png"); replace that value with the
official BUSD logo value used in your Polygon/BSC token entries (copy the exact
"image" field string from those BUSD entries so the Cardano Milkomeda entry
points to the same CoinGecko logo), preserving JSON syntax and casing.
Summary by CodeRabbit