Title: Gno.land indexer & GraphQL
Source: https://nodely.io/docs/gno/indexer/

# Gno.land indexer & GraphQL

The gno.land node has no transaction search. Nodely runs the [gno.land tx-indexer](https://github.com/gnolang/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.

<a id="endpoints"></a>

## Endpoints

All on the same host as the [public RPC](https://nodely.io/docs/gno), `gnot.nodely.dev`:

| Service | Endpoint |
| --- | --- |
| GraphQL API (queries and subscriptions) | `https://gnot.nodely.dev/graphql/query` |
| GraphQL playground | [`https://gnot.nodely.dev/graphql`](https://gnot.nodely.dev/graphql) |
| Indexer JSON-RPC | `https://gnot.nodely.dev/indexer` |
| Indexer websocket (`newHeads`) | `wss://gnot.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.

<a id="graphql"></a>

## GraphQL

<a id="search-transactions"></a>

### 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:

```graphql
{
  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:

```graphql
{
  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:

```graphql
{
  getTransactions(where: {
    block_height: { gt: 980000 }
    messages: { value: { MsgAddPackage: {} } }
  }) {
    hash
    block_height
    messages {
      value {
        ... on MsgAddPackage { creator package { name path } }
      }
    }
  }
}
```

With curl:

```bash
curl https://gnot.nodely.dev/graphql/query \
  -H 'Content-Type: application/json' \
  -d '{"query":"{ latestBlockHeight }"}'
```

<a id="live-updates"></a>

### 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.

```graphql
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.

<a id="supply"></a>

### Supply

```graphql
{
  getSupply(denom: "ugnot") { height total spendable locked }
}
```

`spendable` is what data aggregators call the circulating supply.

<a id="json-rpc"></a>

## JSON-RPC

POST JSON-RPC 2.0 requests to `https://gnot.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.

```bash
curl https://gnot.nodely.dev/indexer \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"getGasPrice","params":[]}'
```

<a id="new-block-headers"></a>

### New block headers

Over `wss://gnot.nodely.dev/indexer/ws` you can subscribe to new block headers. This is the push feed the node’s own websocket lacks:

```json
{ "jsonrpc": "2.0", "id": 1, "method": "subscribe", "params": ["newHeads"] }
```

Each notification carries the header as base64 Amino binary.

<a id="limits"></a>

## 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](https://nodely.io/contact) about dedicated or [whitelabel](https://nodely.io/docs/whitelabel) endpoints.
