Docs
Home Launch app
Documentation

Honest mode,
for everyone.

diodegenes reads a Solana coin the way a careful person would before buying it: who made it, what they still hold, where they quietly sent the rest, and whether anyone can still print or freeze tokens. It does it from your browser in about a second and links every answer to the chain.

What it answers#

  • Can the supply change? If the mint authority is still on, more coins can appear tomorrow.
  • Can your wallet be locked? If the freeze authority is still on, someone can stop you from selling.
  • Who is the dev, and how many coins have they made? A wallet that launched 4,000 coins is not attached to this one.
  • How much does the dev control, really? What sits in their wallet plus what they moved into other wallets that still hold it.
  • Is anyone actually trading? Concentration, liquidity and how much of the volume looks like people.

What it is not#

diodegenes does not hold your funds, ask for a wallet or sign anything. It has no server of its own: the page talks to a public Solana node and a public token API directly. If the site disappeared tomorrow, lib/diodegenes.js would still run from any copy.

Quick start#

Two ways in. Both run the same code.

In the app#

  1. Open the app and paste a contract address.
  2. Press Check the dev. The log shows each read as it happens.
  3. Read the verdict, then the lines under it. Every line has a link to the account or transaction it came from.
  4. Press Copy link to share the check. The address goes into the URL, so the link reruns it fresh for whoever opens it.

From code#

import { check } from "SITE/lib/diodegenes.js";

const r = await check("DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263");
console.log(r.verdict);          // "Honest", "Suspicious" or "Not honest"
r.checks.forEach((c) => console.log(c.status, c.label, c.value));
# the two public reads diodegenes.js starts with
curl -s "https://lite-api.jup.ag/tokens/v2/search?query=DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"

curl -s https://solana-rpc.publicnode.com -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"getAccountInfo","params":["DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",{"encoding":"jsonParsed"}]}'
<p id="verdict">Checking…</p>
<script type="module">
  import { check } from "SITE/lib/diodegenes.js";
  const r = await check("DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263");
  document.getElementById("verdict").textContent = r.verdict;
</script>
NOTEThe module runs in any modern browser and in Node 18 or newer. It uses fetch and crypto.subtle, nothing else.

One check, start to end#

What happens between pressing the button and seeing the verdict.

  1. Ask the token API who made it. One request returns the creator wallet, how many coins it has launched, its current share, the top-10 share, liquidity and an organic trading score.
  2. Read the mint account from the chain. One getAccountInfo call returns the mint and freeze authorities and the true supply. Chain data wins over the API whenever both exist.
  3. Find the dev's token account. The address is derived, not looked up: the associated token account of the creator wallet for this mint. It exists even if the dev already closed it.
  4. Follow its last 20 moves. getSignaturesForAddress lists them, getTransaction opens each one, and every plain token transfer out of the account is kept.
  5. Drop the trades. If the receiving token account belongs to a program (a pool, a bonding curve, a lock), the transfer was a trade. If it belongs to a wallet, it was a gift.
  6. Count what the gifts still hold. One getAccountInfo per receiving account, summed and divided by supply.
  7. Apply the rules. Each line becomes pass, warn or fail. One fail makes the coin Not honest; two warnings make it Suspicious.

A typical check makes between 3 and 45 requests and finishes in under two seconds. Coins whose dev account never moved finish in three.

The checks#

Eight lines, in the order the app shows them.

LineQuestionRead from
mintCan anyone print more?Mint account on chain, mintAuthority
freezeCan anyone freeze your tokens?Mint account on chain, freezeAuthority
serialHow many coins has the creator wallet launched?Token API, audit.devMints
devholdsWhat share does the creator wallet hold right now?Token API, audit.devBalancePercentage
hiddenWhat share sits in wallets the dev sent tokens to?Chain: the dev's token account, its transactions, the receivers
topWhat share do the ten largest wallets hold?Token API, audit.topHoldersPercentage
liquidityHow deep is the pool?Token API, liquidity in USD
organicDoes the volume look like people?Token API, organicScoreLabel

Authorities#

A mint authority can create new tokens at any time and dilute every holder. A freeze authority can freeze any token account, which means you hold the coin and cannot sell it. Most launchpads revoke both at creation. When either is still on, nothing else about the coin matters much, so both are hard fails.

The dev#

The creator is the wallet that signed the coin's creation. A wallet with one or two launches is a person trying something. A wallet with dozens or thousands is a machine that makes coins, and this coin is one of its outputs. The current share is read in plain sight; the hidden share is the next section.

The crowd#

The top-10 share excludes pools and locks, so a coin with most of its supply in a liquidity pool is not punished for it. Liquidity under $5,000 means one ordinary sell can move the price by double digits. The organic score is the token API's estimate of how much volume comes from wallets that behave like people rather than bots trading with themselves.

Fresh wallets#

The oldest trick in the market: split the bag so nobody sees it.

A dev who holds 12% looks greedy. The same dev with 0% in the main wallet and 4% in each of three new wallets looks clean on any holder chart. Each of those transfers is still a transaction signed by the dev's token account, and the chain keeps it.

How the trace works#

lib/diodegenes.js
import { traceTransfers, DEFAULT_RPC, TOKEN_2022 } from "SITE/lib/diodegenes.js";

const out = await traceTransfers(
  DEFAULT_RPC,
  "8Xq4z469zp2QevkpvMAd9kvPUtRAxK8aayViMN5rji2",   // creator wallet
  "ECW3x9jPetgg587DMKDP8uVJS9EyoGfcZN7wdaQmpump",   // the coin
  TOKEN_2022,                                      // its token program
  20                                               // how many moves to read
);
// { devTokenAccount, read, wallets: [{ wallet, tokenAccount, amount, signature }] }

Wallet or program#

Every Solana address is 32 bytes. A wallet address is a point on the ed25519 curve, because it has a private key. A program-derived address is deliberately off the curve, because nobody may hold a key for it. Pools, bonding curves and lockers own their token accounts through such addresses. isOnCurve() decides which side a receiver is on with plain field arithmetic, so a sell into a pool is never counted as hiding.

NOTETransfers to the dev's own main wallet are skipped too. Moving tokens between your own accounts is not hiding.

Verdict rules#

Numbers are percent of total supply unless marked.

Linewarn fromfail from
mint—authority is set
freeze—authority is set
serial5 coins20 coins
devholds5%15%
hidden1%5%
top30%50%
liquidityunder $5,000—
organiclabel is low—
VerdictWhen
Not honestAt least one fail
SuspiciousNo fails, two or more warnings
HonestNo fails, at most one warning

You can pass your own thresholds: check(mint, { rules: { devHoldsFail: 10 } }). Anything you leave out keeps the default from RULES.

WARNINGHonest means the lantern found nothing it looks for. It does not mean the price will go up, and it does not mean the team will keep building.

diodegenes.js#

One ES module at /lib/diodegenes.js. The app imports it, so do you.

ExportDoes
check(mint, opts?)Runs every line and returns a result. Options: rpc, onStep(text), traceLimit, rules.
traceTransfers(rpc, dev, mint, program, limit?, onStep?)Follows the dev's token account and returns the wallets it sent tokens to.
fetchToken(mint)The raw token API record, or null.
rpc(url, method, params)A JSON-RPC call with backoff on rate limits.
ata(owner, mint, program?)The associated token account address, derived locally.
findProgramAddress(seeds, programId)Solana's program address derivation in 15 lines.
isOnCurve(bytes)True for wallets, false for program addresses.
isAddress(text)True if the text decodes to 32 bytes of base58.
b58decode, b58encodeBase58 both ways.
RULES, DEFAULT_RPC, TOKEN_APIThe defaults described on this page.
progress and your own node
import { check } from "SITE/lib/diodegenes.js";

const r = await check(mint, {
  rpc: "https://your-node.example",           // any Solana JSON-RPC that allows browsers
  traceLimit: 50,                             // read more of the dev's history
  onStep: (text) => console.log("·", text),   // the same lines the app logs
});

Try it#

This box imports ../lib/diodegenes.js and runs it on whatever you paste.

// paste a contract and press Run

Put a verdict on your page#

A dev who checks their own coin in public has nothing to hide. Or is very confident.

<span id="honest">Holding the lantern…</span>
<script type="module">
  import { check } from "SITE/lib/diodegenes.js";
  const CA = "PASTE_YOUR_CONTRACT";
  const r = await check(CA);
  const el = document.getElementById("honest");
  el.textContent = "diodegenes says: " + r.verdict;
  el.onclick = () => open("SITE/app/?ca=" + CA);
</script>
// Node 18+: save as check.mjs, run with: node check.mjs <CA>
import { check } from "SITE/lib/diodegenes.js";
const r = await check(process.argv[2]);
console.log(r.verdict + "\n" + r.checks.map((c) => c.status + "  " + c.label + ": " + c.value).join("\n"));
NOTENode does not import from URLs. Download diodegenes.js next to your script and import ./diodegenes.js instead.

Result format#

check() returns
{
  version: "1.0.0",
  mint: "ECW3x9jPetgg587DMKDP8uVJS9EyoGfcZN7wdaQmpump",
  name: "Fireant", symbol: "…",
  dev: "8Xq4z469zp2QevkpvMAd9kvPUtRAxK8aayViMN5rji2",
  supply: 977796270.7, program: "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb",
  launchpad: "pump.fun", createdAt: "2026-10-26T11:30:06Z",
  verdict: "Honest", fails: 0, warns: 1,
  checks: [
    { id: "mint", label: "Can anyone print more", status: "pass", value: "No",
      detail: "Mint authority is revoked. The supply is final.", source: "https://solscan.io/account/…" },
    // …
  ],
  hidden: [],                 // wallets the dev sent tokens to, if any
  checkedAt: "2026-10-26T12:02:39.000Z"
}
statusMeaning
passNothing to worry about on this line
warnWorth a look; two of these make the coin Suspicious
failOne is enough for Not honest
skipThe data was not available; the line does not count either way

Data sources#

SourceUsed forAddress
Solana nodeMint account, the dev's token account, its transactions, receiverssolana-rpc.publicnode.com
Jupiter token APICreator wallet, launches, shares, liquidity, organic scorelite-api.jup.ag/tokens/v2
SolscanLinks only, nothing is read from itsolscan.io
DexScreenerChart link and the "newest coin" button in the appapi.dexscreener.com

The story of the lantern is in Diogenes Laërtius, Lives of Eminent Philosophers, book VI, 41. The painting on the home page is Jacob Jordaens, Diogenes Searching for an Honest Man, about 1642, Gemäldegalerie Alte Meister, Dresden, in the public domain.

Limits#

What a lantern cannot see.

  • Twenty moves deep. The trace reads the last 20 transactions of the dev's token account. A dev who split the bag long ago and then traded a lot can push the split out of view. Raise traceLimit for a deeper look.
  • One hop. Tokens sent from the dev to wallet A and then from A to wallet B are counted at A only. If A is empty, the trail ends there.
  • Bought, not sent. A dev who funds fresh wallets with SOL and has them buy on the open market leaves no token transfer to follow. Look at the top-10 share and the organic score for that.
  • The token API can be wrong. Creator, launches and shares come from Jupiter's index. The authorities are always re-read from the chain.
  • Public nodes have limits. If the log stops at "Following the dev's token account", the node is rate limiting you. Wait a minute, or paste your own node under Your own Solana node in the app.

$DIODEGENES#

The coin of the lantern, checked by the lantern.

Contractsoon

The home page runs the same check on $DIODEGENES that you can run on any coin, live, every time someone opens it. If a line goes red, it goes red in public.

FAQ#

Does it cost anything?#

No. There is no server to pay for: your browser does the reads.

Do I need a wallet?#

No. Nothing is signed and nothing is connected.

Why does an old blue chip come out Suspicious?#

Large old coins often have concentrated top wallets (exchanges) and creators who launched other tokens. The lantern reports what it sees. Read the lines, not just the word.

Other chains?#

Solana only. The address math, the token programs and the node calls are all Solana-specific.

Did Diogenes ever find one?#

The sources say no. He kept the lantern lit anyway.

diodegenes · diodegenes.js 1.0.0Back to top ↑