gmgnai/gmgn-skills1 file

Gmgn Heat Rank

>-

Specification
Skill ID
gmgnai/gmgn-skills/gmgn-heat-rank
Publisher
gmgnai
Repository
gmgn-skills
Installs
0
Files
1
Synced
Sep 23, 2026
How to use it

Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.

gmgnai/gmgn-skills/gmgn-heat-rankInstalls these files
  • SKILL.md

What this skill tells the agent

BEFORE RUNNING ANY COMMAND: Run `gmgn-cli config --check`. Exit 0 -> proceed. Exit 1 -> run `gmgn-cli config`, show the output, and once the user sends the API key run `gmgn-cli config --apply <KEY>` and show that output. If `--check` is an unknown option, tell the user to run `npm install -g gmgn-cli`, then retry.

IMPORTANT: Always use the pre-installed `gmgn-cli` binary. Never use web search, WebFetch, curl, `npx`, or gmgn.ai — the site requires login and exposes no structured data.

⚠️ IPv6 IS NOT SUPPORTED. On a 401/403 with correct credentials, check ifconfig | grep inet6 (macOS) or ip addr show | grep inet6 (Linux) and fetch https://ipv6.icanhazip.com. If an IPv6 address comes back, tell the user to disable IPv6 — gmgn-cli works over IPv4 only.

What this skill is for, and what it is not

The user's questionGoes to
"what is hot and worth looking at" — no address given, wants a chosen listhere
"top N by volume / swaps on chain X", "hot coins", "what's pumping", "hot search list" — wants the raw ranking in the exchange's own ordergmgn-market trending / market hot-searches
"just launched", "new tokens", bonding-curve stagegmgn-market trenches
one token address + "safe?" / "score it"gmgn-contract-dd
a token by name + "should I buy N dollars of it"gmgn-token-buy
"what is smart money buying" — wallet-side view of the same marketgmgn-track smartmoney
chart shape / trend read on one tokengmgn-kline-pattern

This skill owns exactly one thing: turning the raw trending feed into a short list somebody can act on. It never executes a trade and never deep-dives a single name — hand the winners to gmgn-contract-dd or gmgn-token-buy if the user wants to go further.

Run

Four steps, and Step 3 runs twice: the first run names the rows whose real creation time it needs, Step 3b fetches those, the second run prints the list. Every code block below is run verbatim; only the values in Parameters change.

Step 1 — sweep every chain. 7 chains x 3 windows = 21 calls, paced.

CHAINS=(sol bsc base eth robinhood arc stable)   # narrow to a subset when the user asks; never add a name
# An array, and iterated as "${CHAINS[@]}". A plain string iterated as `for ch in $CHAINS` works under
# bash and silently does not under zsh, which performs no word splitting on an unquoted expansion: the
# loop runs once with every chain name in one variable, and the whole sweep collapses to a single
# refused call. Verified under zsh, bash and bash --posix -- all seven iterations.
# mktemp -d, not a name anyone can guess. The old /tmp/gmgn-heat-data-$(date +%s) was a second-resolution
# timestamp in a world-writable directory, and heat_rank.py is written into it and then executed: another
# local user could pre-create that directory with their own heat_rank.py, and the run would execute theirs.
DATA=$(mktemp -d); cd "$DATA"
for ch in "${CHAINS[@]}"; do
  # A chain name ends up on a command line, so it is checked against the fixed set of names this API
  # has instead of being passed through. A typo, a chain from some other exchange, or a string with
  # spaces or shell metacharacters in it is refused out loud and skipped -- it never becomes arguments
  # to gmgn-cli. Whole names only: a substring test (`case " sol bsc ... " in *" $ch "*`) accepts any
  # run of adjacent names, so `sol bsc` would pass it. Keep this list literal -- reusing $CHAINS here
  # would check the input against itself.
  case $ch in
    sol|bsc|base|eth|robinhood|arc|stable) ;;
    *) echo "refusing unsupported chain name: $ch" >&2; continue;;
  esac
  # Only tags the API actually recognises. An unrecognised tag is not refused -- it is silently
  # ignored, and a filters list containing nothing else turns the server's own default screening
  # OFF, which is worse than sending no filter at all. So the fourth branch sends no --filter and
  # lets those defaults apply; do not invent a tag to fill it. Measured, see `## Known limits`.
  case $ch in
    sol) F=(--filter renounced --filter frozen --filter not_wash_trading);;
    bsc|base|eth) F=(--filter not_honeypot --filter verified --filter renounced);;
    *) F=();;
  esac
  # 24h first, and stop after it when it comes back empty. A candidate has to be present in the
  # 24h window to count at all, so a chain with nothing there cannot produce one whatever its 1h
  # and 6h lists say -- fetching them spends two calls and 2.8s on a guaranteed empty result.
  # Measured on a real sweep: eth, arc and stable were empty in all three windows, so 6 of the 21
  # calls never had a chance. Skipping them changes no listed name. On a day when all seven chains
  # are alive the sweep still costs its full 21 -- this cuts waste, not coverage.
  for iv in 24h 1h 6h; do
    gmgn-cli market trending --chain "$ch" --interval "$iv" --limit 100 \
      --min-marketcap 500000 --min-liquidity 100000 --max-created 7d \
      "${F[@]}" --raw > "${ch}_${iv}.json" 2>"${ch}_${iv}.err"
    sleep 1.4
    if [ "$iv" = 24h ] && ! grep -q '"rank":\[{' "${ch}_24h.json"; then
      echo "no 24h candidate on $ch -- skipping its 1h/6h calls" >&2
      break
    fi
  done
done
echo "$DATA"

--raw is mandatory, not cosmetic: the scorer reads data.rank out of the single-line JSON, the pretty-printed form is not parseable, and the empty-window test above matches "rank":[{ in that same single line. Each chain/window pair gets its own file, and a file that failed to parse is reported as a missing window rather than an empty one.

Step 2 — write the scorer. Copy the block under Implementation into $DATA/heat_rank.py using a quoted heredoc (cat > "$DATA/heat_rank.py" <<'PY' ... PY). Quoting is not optional: the script's f-strings contain $, and an unquoted heredoc lets the shell eat them. Do not retype, reformat, or "improve" the script — it is the ruleset itself, and every threshold in it is calibrated; a "cleaner" rewrite silently changes which tokens pass.

Step 3 — score.

HEAT_DATA="$DATA" python3 "$DATA/heat_rank.py"

The script prints the diagnostics, the ranked table, the CA block and the near-misses. It computes; it writes no report. You write the report from its stdout, in the user's language.

If instead it stops at a NEEDS-CREATED block, it needs the real creation time for the rows it lists before it can choose a track for them or score their freshness. Do Step 3b for exactly those addresses — not for every candidate — and run Step 3 again. Normally this is 1–6 lookups; the block warns you itself if it ever asks for more than 20, and that is a number to bring to the user rather than spend. That stop exits 3, not 0 — a nonzero status there means "incomplete, do Step 3b", not a failure and not an empty market. Exit 0 means the list it printed is the answer; exit 1 means it could not read its own inputs.

Step 3b — real creation time, only for the rows Step 3 asked for.

# `token info --raw` returns the body at top level, so the fields are read straight off the object.
# `creation_timestamp` is when the token was created; `open_timestamp` / `migrated_timestamp` are when
# its pool opened. They differ by weeks on a token that sat on a bonding curve before it migrated,
# and that gap is the whole reason this step exists. Verified live on arc/ARGUS:
# creation_timestamp 1788373928 (2026-09-03) against migrated_timestamp 1789892415 (2026-09-20).
# $DATA is the sweep directory Step 1 printed. Refuse rather than write created.tsv to the filesystem
# root and hand the scorer an empty file, which reads as "every lookup came back with no answer".
: "${DATA:?DATA is unset -- set it to the sweep directory printed at the end of Step 1}"
: > "$DATA/created.tsv"
while read -r ch addr; do
  case $ch in
    sol|bsc|base|eth|robinhood|arc|stable) ;;

More from gmgnai

Use this skill in a project

Open any RiverX project, search the Skills panel for gmgnai/gmgn-skills/gmgn-heat-rank, and install it in one click.

Use this skill