Gno.land indexer & GraphQL
The gno.land node has no transaction search. Nodely runs the gno.land tx-indexer next to its archive nodes to fill that gap: search transactions by sender, recipient, realm or message type, and follow new blocks and transactions in real time.
Endpoints
Section titled “Endpoints”All on the same host as the public RPC, gno.nodely.dev:
| Service | Endpoint |
|---|---|
| GraphQL API (queries and subscriptions) | https://gno.nodely.dev/graphql/query |
| GraphQL playground | https://gno.nodely.dev/graphql |
| Indexer JSON-RPC | https://gno.nodely.dev/indexer |
Indexer websocket (newHeads) |
wss://gno.nodely.dev/indexer/ws |
- gno.land mainnet (
gnoland-1), full history from block 1. - No account, no keys. CORS is open, so browser apps can call it directly.
- The playground documents every query, field and filter.
GraphQL
Section titled “GraphQL”Search transactions
Section titled “Search transactions”getTransactions takes a where filter on any transaction field, including message contents. Filters support eq, gt, lt and exists, combined with _and, _or and _not.
There is no result limit, so always scope a search with block_height.
Incoming transfers to an address:
{ getTransactions(where: { block_height: { gt: 980000 } messages: { value: { BankMsgSend: { to_address: { eq: "g1..." } } } } }) { hash block_height success messages { value { ... on BankMsgSend { from_address to_address amount } } } }}Calls to a realm:
{ getTransactions(where: { block_height: { gt: 980000 } messages: { value: { MsgCall: { pkg_path: { eq: "gno.land/r/..." } } } } }) { hash block_height messages { value { ... on MsgCall { caller pkg_path func } } } }}Packages and realms deployed:
{ getTransactions(where: { block_height: { gt: 980000 } messages: { value: { MsgAddPackage: {} } } }) { hash block_height messages { value { ... on MsgAddPackage { creator package { name path } } } } }}With curl:
curl https://gno.nodely.dev/graphql/query \ -H 'Content-Type: application/json' \ -d '{"query":"{ latestBlockHeight }"}'Live updates
Section titled “Live updates”Subscriptions run on the same /graphql/query path over a websocket (graphql-transport-ws protocol, which standard GraphQL clients use). They deliver blocks or transactions created after the subscription starts.
subscription { getBlocks(where: {}) { height time num_txs }}getTransactions works as a subscription too, with the same filters. For example, a wallet can watch for incoming transfers.
Supply
Section titled “Supply”{ getSupply(denom: "ugnot") { height total spendable locked }}spendable is what data aggregators call the circulating supply.
JSON-RPC
Section titled “JSON-RPC”POST JSON-RPC 2.0 requests to https://gno.nodely.dev/indexer.
| Method | Params | Returns |
|---|---|---|
getTxResultByHash |
[hash], base64 |
transaction result, base64 Amino |
getTxResult |
[height, index] |
transaction result, base64 Amino |
getBlock |
["height"] |
block, base64 Amino |
getSupply |
["ugnot"] |
{ denom, height, total, spendable, locked } |
getGasPrice |
[] |
[{ denom, low, average, high }] |
Transaction and block results come back as base64 Amino binary. Use GraphQL when you want JSON.
curl https://gno.nodely.dev/indexer \ -H 'Content-Type: application/json' \ -d '{"jsonrpc":"2.0","id":1,"method":"getGasPrice","params":[]}'New block headers
Section titled “New block headers”Over wss://gno.nodely.dev/indexer/ws you can subscribe to new block headers. This is the push feed the node’s own websocket lacks:
{ "jsonrpc": "2.0", "id": 1, "method": "subscribe", "params": ["newHeads"] }Each notification carries the header as base64 Amino binary.
Limits
Section titled “Limits”Per client IP:
- 5 requests per second (burst 20 for GraphQL, 40 for JSON-RPC)
- 8 concurrent requests
- Requests over the limit get HTTP 429
Need more? Talk to us about dedicated or whitelabel endpoints.