Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

sharing mygnoscan

2026-09-23 · #mygnoscan · #tooling · #explorer

mygnoscan is a BI tool I wrote to answer my own questions about gno.land. I have been adding to it since April and never announced it, because it is not finished and it will not be.

Then people found it, said they liked it, and asked when I would share it. So: here it is. Not a product, not official, and I add to it every time it fails to answer a new question.

what I actually open it for

Generic explorers are built around blocks and transactions. Those are table stakes. My questions were a different shape: what is deployed, who calls it, and what changed this week.

So the front page is a window, not a ledger. Pick a range, see it against the range before it, then five lists:

  • hot realms, by calls, with the caller count beside them. 3,817 calls from 26 addresses and 4,998 from 461 are not the same event, and one number cannot tell you which you are looking at.
  • hot assets: ugnot at 19,280 transfers from 980 senders, GNS at 6,324 from 141.
  • hot developers, flagged when it is their first deploy ever. Three of the top four this week are first-timers.
  • hot libraries, ranked by new importers rather than total. p/nt/ufmt took 23 new importers this week against 113 all time.
  • notable transfers.

Under that: realm source, imports, dependents, callers, the MsgRun scripts that use a realm without importing it, a dependency graph, and screenshots of what each realm actually looks like.

two things the indexer taught me

Half of this is a frontend. The other half is learning how the tx-indexer actually behaves, which is where the interesting bugs live.

There is no pagination. getTransactions takes where and order, and nothing else. The server caps a result set at 10,000 elements, and on reaching it the resolver stops and returns the rows it has alongside a GraphQL error. So a capped response is partial, not empty, and the only way to walk a larger set is the block height filter:

1getTransactions(where: {
2  block_height: { gt: 250000, lte: 260000 }
3}) { hash block_height }

Read that wrong and you show a truncated history as if it were complete.

One unknown type kills every query. Message types are selected inside one shared fragment set:

1messages { value { __typename
2  ... on MsgCall          { caller pkg_path func args }
3  ... on MsgAddPackage    { creator package { name path } }
4  ... on MsgEnablePackage { approver pkg_path }
5} }

An indexer that does not define MsgEnablePackage rejects every transaction query, not just the ones that would have matched it:

sync packages: indexer returned 422: Unknown type "MsgEnablePackage"

That took a whole chain's sync offline. And the types shipped separately, so mainnet defines MsgEnablePackage and not MsgCreateSession: probing for one and selecting the other fails every query while reporting support.

where I want to take it

A developer section, mostly. Realm state as a readable tree instead of a blob. Code search across every .gno file on chain. A time machine, because the chain overwrites state and the indexer is the only thing watching. And a read-only endpoint so an agent can ask what I ask through the UI.

please break it

gnoverse/mygnoscan. One Go binary, the frontend embedded, SQLite for the graph analysis. The README says how to run your own against your own node, which I would like more people to do.

What I want most is an issue when it does not answer your question. Every feature in there came from a question I could not answer, and I only have mine. Second most: tell me when a number looks wrong. Some have been, and an explorer that is confidently wrong is worse than none.

I am not building the explorer for gno.land. gnoscan.io is the one to hand a stranger. I am building the one I want open in a tab while I work, and it turns out a few other people want that tab too.


← all posts