# Zenith Watcher API The Zenith Watcher indexes the Zenith blockchain across all network stages, providing access to account information, transactions, validators, scry bindings, and treasury claims. **GraphQL Endpoint**: `https://zenith-watcher.zenith-test.tlon.systems/graphql` ## GraphQL API ### Query Account Information ```graphql query GetAccount($address: String!) { account(address: $address) { address balances { denom amount } transactions { hash type timestamp blockHeight success } } } ``` ### Query Transactions ```graphql query GetTransactions($address: String!, $limit: Int!) { transactions( where: { or: [ { sender: $address } { receiver: $address } ] } limit: $limit orderBy: timestamp orderDirection: desc ) { hash sender receiver amount denom timestamp blockHeight success } } ``` ### Query Validators ```graphql query GetValidators { validators { address moniker votingPower commission jailed uptime } } ``` ### Query Scry Bindings ```graphql query GetScryBindings($path: String!) { scryBindings(where: { path: $path }) { path hash blockHeight timestamp signatures { signer signature } } } ``` ### Query Treasury Claims ```graphql query GetClaims($address: String!) { treasuryClaims(where: { claimer: $address }) { claimer amount denom timestamp blockHeight transactionHash } } ``` ## REST API The Zenith Watcher also provides REST API endpoints for querying scry oracle data. ### 1. Get Binding by Path The `/laconic/scryoracle/v1/binding_by_path` API retrieves the binding (hash, block number, and block hash) for a specific path. **Example:** ```bash curl -X 'GET' -H 'accept: application/json' \ "http://127.0.0.1:3008/rest/laconic/scryoracle/v1/binding_by_path?path=/~zod/group-store/groups/random-group/json" | jq ``` **Response:** ```json { "binding": { "hash": "d5af5fddee9de5cedbe1ad1df367f96f67347f8edaddef75", "block_number": "23", "block_hash": "a9521112d4ee58da8221c893c8dae465b236456c4becc25edffe85ae3b0ac15e" }, "binding_with_verification": null } ``` **With include_verification_data parameter:** ```bash curl -X 'GET' -H 'accept: application/json' \ "http://127.0.0.1:3008/rest/laconic/scryoracle/v1/binding_by_path?path=/~zod/group-store/groups/random-group/json&include_verification_data=true" | jq ``` **Parameters:** - `path` (required): The exact path to lookup - `include_verification_data` (optional): Whether to return signature and life (default: false) ### 2. Get Bindings by Path Prefix The `/laconic/scryoracle/v1/bindings_by_prefix` API gets path-to-hash mappings using a path prefix with support for both cursor-based and offset-based pagination. #### Cursor-based Pagination **Example - First page:** ```bash curl -X 'GET' -H 'accept: application/json' \ "http://127.0.0.1:3008/rest/laconic/scryoracle/v1/bindings_by_prefix?path_prefix=/~zod&pagination.limit=3" | jq ``` **Response:** ```json { "path_bindings": { "/~zod/group-store/groups/random-group/json": { "hash": "d5af5fddee9de5cedbe1ad1df367f96f67347f8edaddef75", "block_number": "23", "block_hash": "a9521112d4ee58da8221c893c8dae465b236456c4becc25edffe85ae3b0ac15e" }, "/~zod/group-store/members/random-group/json": { "hash": "77873b7b96bd7f4d5bddff366ba6f6779738edad1fddef75", "block_number": "23", "block_hash": "a9521112d4ee58da8221c893c8dae465b236456c4becc25edffe85ae3b0ac15e" }, "/~zod/metadata-store/associations/groups/random-group/json": { "hash": "73b7b96bd77a6f47f5ddff367786b57366f97bd7f8edad37", "block_number": "23", "block_hash": "a9521112d4ee58da8221c893c8dae465b236456c4becc25edffe85ae3b0ac15e" } }, "pagination": { "next_key": "eyJwYWdpbmF0aW9uX3NraXAiOjN9", "total": "0" } } ``` !!! note "Using next_key" Use `next_key` from pagination output of the above API response in a subsequent request (as `pagination.key`) to get the next page of results. **Example - Next page using next_key:** ```bash curl -X 'GET' -H 'accept: application/json' \ "http://127.0.0.1:3008/rest/laconic/scryoracle/v1/bindings_by_prefix?path_prefix=/~zod&pagination.key=eyJwYWdpbmF0aW9uX3NraXAiOjN9" | jq ``` #### Offset-based Pagination **Example:** ```bash curl -X 'GET' -H 'accept: application/json' \ "http://127.0.0.1:3008/rest/laconic/scryoracle/v1/bindings_by_prefix?path_prefix=/~zod&pagination.limit=10&pagination.offset=2&pagination.count_total=true" | jq ``` **Parameters:** - `path_prefix` (required): The path prefix to match against - `pagination.limit` (optional): Number of results per page (default: 100) - `pagination.key` (optional): Base64-encoded cursor for next page - `pagination.offset` (optional): Offset for traditional pagination (cannot be used with key) - `pagination.count_total` (optional): Whether to return total count (default: false) - `include_verification_data` (optional): Whether to return signature and life (default: false) !!! warning "Pagination Note" You cannot use both `pagination.key` and `pagination.offset` in the same request. ### 3. Get Bindings by Block Number The `/laconic/scryoracle/v1/bindings_by_block_number` API gets path-to-hash mappings added at a specific block number. **Example:** ```bash curl -X 'GET' -H 'accept: application/json' \ "http://127.0.0.1:3008/rest/laconic/scryoracle/v1/bindings_by_block_number?block_number=25&path_prefix=/~zod" | jq ``` **Response:** ```json { "path_bindings": { "/~zod/publish/comments/2025.3.6..15.30.20..0000/json": { "hash": "6b477973b7fdd5ee9be367f76fd6b577cd9cd1fe3b7b9dda", "block_number": "25", "block_hash": "5a932989009ea3ed054e8a98752eea09384e3bf134ebeb833984f11e52ea8bf5" }, "/~zod/publish/posts/2025.3.6..15.30.20..0000/json": { "hash": "ddff757786bb6f4d9ce9ee5af5ff376f57397746b8ef67ba", "block_number": "25", "block_hash": "5a932989009ea3ed054e8a98752eea09384e3bf134ebeb833984f11e52ea8bf5" } } } ``` **Parameters:** - `block_number` (required): The block number to query - `path_prefix` (optional): Filter results by path prefix - `include_verification_data` (optional): Whether to return signature and life (default: false) ### 4. Get Bindings in Block Range The `/laconic/scryoracle/v1/bindings_in_block_range` API gets path-to-hash mappings added within a block range. **Example:** ```bash curl -X 'GET' -H 'accept: application/json' \ "http://127.0.0.1:3008/rest/laconic/scryoracle/v1/bindings_in_block_range?from_block=10&to_block=100&path_prefix=/~zod/publish" | jq ``` **Response:** ```json { "path_bindings": { "/~zod/publish/comments/2025.3.6..15.30.20..0000/json": { "hash": "6b477973b7fdd5ee9be367f76fd6b577cd9cd1fe3b7b9dda", "block_number": "25", "block_hash": "5a932989009ea3ed054e8a98752eea09384e3bf134ebeb833984f11e52ea8bf5" }, "/~zod/publish/posts/2025.3.6..15.30.20..0000/json": { "hash": "ddff757786bb6f4d9ce9ee5af5ff376f57397746b8ef67ba", "block_number": "25", "block_hash": "5a932989009ea3ed054e8a98752eea09384e3bf134ebeb833984f11e52ea8bf5" } } } ``` **Parameters:** - `from_block` (required): Starting block number (inclusive) - `to_block` (required): Ending block number (inclusive) - `path_prefix` (optional): Filter results by path prefix - `include_verification_data` (optional): Whether to return signature and life (default: false) !!! note "Block Range Limit" The block range is limited to 1000 blocks maximum. ### 5. Get Bindings by Wildcard Pattern The `/laconic/scryoracle/v1/bindings_by_wildcard` API gets path-to-hash mappings using wildcard pattern matching with support for both cursor-based and offset-based pagination. **Example - Match any path between ~zod and random-group/json:** ```bash curl -X 'GET' -H 'accept: application/json' \ "http://127.0.0.1:3008/rest/laconic/scryoracle/v1/bindings_by_wildcard?path_pattern=/~zod/*/random-group/json" | jq ``` **Response:** ```json { "path_bindings": { "/~zod/group-store/groups/random-group/json": { "hash": "d5af5fddee9de5cedbe1ad1df367f96f67347f8edaddef75", "block_number": "23", "block_hash": "a9521112d4ee58da8221c893c8dae465b236456c4becc25edffe85ae3b0ac15e" }, "/~zod/group-store/members/random-group/json": { "hash": "77873b7b96bd7f4d5bddff366ba6f6779738edad1fddef75", "block_number": "23", "block_hash": "a9521112d4ee58da8221c893c8dae465b236456c4becc25edffe85ae3b0ac15e" }, "/~zod/metadata-store/associations/groups/random-group/json": { "hash": "73b7b96bd77a6f47f5ddff367786b57366f97bd7f8edad37", "block_number": "23", "block_hash": "a9521112d4ee58da8221c893c8dae465b236456c4becc25edffe85ae3b0ac15e" } }, "pagination": { "next_key": null, "total": "0" } } ``` **Parameters:** - `path_pattern` (required): The wildcard pattern to match (use `*` for wildcard matching) - `pagination.limit` (optional): Number of results per page (default: 100) - `pagination.key` (optional): Base64-encoded cursor for next page - `pagination.offset` (optional): Offset for traditional pagination (cannot be used with key) - `pagination.count_total` (optional): Whether to return total count (default: false) - `include_verification_data` (optional): Whether to return signature and life (default: false) !!! warning "Pagination Note" You cannot use both `pagination.key` and `pagination.offset` in the same request. ## Using the APIs ### With curl (GraphQL) ```bash # Query Zenith Watcher curl -X POST https://zenith-watcher.zenith-test.tlon.systems/graphql \ -H "Content-Type: application/json" \ -d '{ "query": "query { validators { moniker votingPower jailed } }" }' ``` ### With JavaScript/TypeScript (GraphQL) ```javascript const query = ` query GetAccount($address: String!) { account(address: $address) { balances { denom amount } } } `; const variables = { address: "zenith1..." }; const response = await fetch('https://zenith-watcher.zenith-test.tlon.systems/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query, variables }) }); const data = await response.json(); ``` ### With GraphQL Client Libraries ```javascript import { GraphQLClient } from 'graphql-request'; const client = new GraphQLClient( 'https://zenith-watcher.zenith-test.tlon.systems/graphql' ); const query = ` query GetAccount($address: String!) { account(address: $address) { balances { denom amount } } } `; const data = await client.request(query, { address: 'zenith1...' }); ``` ## Rate Limiting and Best Practices - **Rate Limits**: Public watcher endpoints have rate limiting in place. For production applications, consider running your own watcher instances. - **Pagination**: Use pagination parameters for queries that return large result sets. - **Caching**: Cache frequently accessed data to reduce API load. - **Error Handling**: Implement proper error handling and retry logic for network failures. !!! note "Watcher Documentation" For more information about the watcher architecture and deployment, see the [Watchers documentation](../documentation/watchers.md).