# Azimuth Watcher API The Azimuth Watcher monitors Urbit's Azimuth identity registry on Ethereum, providing access to point ownership, sponsorship relationships, and identity state changes. **GraphQL Endpoint**: `https://azimuth-watcher.zenith-test.tlon.systems/graphql` ## Querying Urbit Point Information The azimuth-watcher is the primary service for querying Urbit identity data. Here are the most common operations: ### 1. Get Point Owner and Basic Info Check who owns a specific Urbit point: ```bash # Example: curl 'https://azimuth.dev.vdb.to/graphql' \ -H 'Content-Type: application/json' \ --data-raw '{"query":"{ azimuthGetOwner(blockHash: \"latest\", contractAddress: \"0x223c067F8CF28ae173EE5CafEa60cA44C335fecB\", _point: 1234) { value } }"}' \ | jq ``` **Response:** ```json { "data": { "azimuthGetOwner": { "value": "0x4b22764F2Db640aB4d0Ecfd0F84344F3CB5C3715" } } } ``` ### 2. Get Cryptographic Keys for a Point Get encryption and authentication keys for networking: ```bash # Example: curl 'https://azimuth.dev.vdb.to/graphql' \ -H 'Content-Type: application/json' \ --data-raw '{"query":"{ azimuthGetKeys(blockHash: \"latest\", contractAddress: \"0x223c067F8CF28ae173EE5CafEa60cA44C335fecB\", _point: 58213) { value { encryptionKey: value0 authenticationKey: value1 cryptoSuiteVersion: value2 keyRevisionNumber: value3 } } }"}' \ | jq ``` **Response:** ```json { "data": { "azimuthGetKeys": { "value": { "encryptionKey": "0xc248f759474b16192bd8bdca0bff1b8bff555cd3d118022095331d6d98690c6d", "authenticationKey": "0x21188bac08542730e1c4697636d6fa25968f404470ccf917756f05e28c69045a", "cryptoSuiteVersion": "1", "keyRevisionNumber": "1" } } } } ``` ### 3. Check Point Status Check if a point is active (booted) and has a sponsor: ```bash # Example: curl 'https://azimuth.dev.vdb.to/graphql' \ -H 'Content-Type: application/json' \ --data-raw '{"query":"{ azimuthIsActive(blockHash: \"latest\", contractAddress: \"0x223c067F8CF28ae173EE5CafEa60cA44C335fecB\", _point: 1234) { value } azimuthHasSponsor(blockHash: \"latest\", contractAddress: \"0x223c067F8CF28ae173EE5CafEa60cA44C335fecB\", _point: 1234) { value } azimuthGetSponsor(blockHash: \"latest\", contractAddress: \"0x223c067F8CF28ae173EE5CafEa60cA44C335fecB\", _point: 1234) { value } }"}' \ | jq ``` **Response:** ```json { "data": { "azimuthIsActive": { "value": true }, "azimuthHasSponsor": { "value": true }, "azimuthGetSponsor": { "value": "210" } } } ``` ### 4. Get All Points Owned by an Address Find all Urbit points owned by an Ethereum address: ```bash # Example: curl 'https://azimuth.dev.vdb.to/graphql' \ -H 'Content-Type: application/json' \ --data-raw '{"query":"{ azimuthGetOwnedPoints(blockHash: \"latest\", contractAddress: \"0x223c067F8CF28ae173EE5CafEa60cA44C335fecB\", _whose: \"0x1234567890123456789012345678901234567890\") { value } }"}' \ | jq ``` **Response:** ```json { "data": { "azimuthGetOwnedPoints": { "value": [ "57965", "1234" ] } } } ``` ### 5. Multi-Watcher Queries The gateway server allows querying multiple watchers in a single request: ```graphql { # Check point status (azimuth-watcher) azimuthIsActive( blockHash: "0x2461e78f075e618173c524b5ab4309111001517bb50cfd1b3505aed5433cf5f9" contractAddress: "0x223c067F8CF28ae173EE5CafEa60cA44C335fecB" _point: 1 ) { value } # Check censure count (censures-watcher) censuresGetCensuredByCount( blockHash: "0x2461e78f075e618173c524b5ab4309111001517bb50cfd1b3505aed5433cf5f9" contractAddress: "0x325f68d32BdEe6Ed86E7235ff2480e2A433D6189" _who: 6054 ) { value } # Find a claim (claims-watcher) claimsFindClaim( blockHash: "0x2461e78f075e618173c524b5ab4309111001517bb50cfd1b3505aed5433cf5f9" contractAddress: "0xe7e7f69b34D7d9Bd8d61Fb22C33b22708947971A" _whose: 1967913144 _protocol: "text" _claim: "Shrek is NOT Drek!" ) { value } # Check star release balance (linear-star-release-watcher) linearStarReleaseVerifyBalance( blockHash: "0x2461e78f075e618173c524b5ab4309111001517bb50cfd1b3505aed5433cf5f9" contractAddress: "0x86cd9cd0992F04231751E3761De45cEceA5d1801" _participant: "0xbD396c580d868FBbE4a115DD667E756079880801" ) { value } # Check conditional star release (conditional-star-release-watcher) conditionalStarReleaseWithdrawLimit( blockHash: "0x2461e78f075e618173c524b5ab4309111001517bb50cfd1b3505aed5433cf5f9" contractAddress: "0x8C241098C3D3498Fe1261421633FD57986D74AeA" _participant: "0x7F0584938E649061e80e45cF88E6d8dDDb22f2aB" _batch: 2 ) { value } # Check governance proposals (polls-watcher) pollsGetUpgradeProposalCount( blockHash: "0xeaf611fabbe604932d36b97c89955c091e9582e292b741ebf144962b9ff5c271" contractAddress: "0x7fEcaB617c868Bb5996d99D95200D2Fa708218e4" ) { value } # Check NFT balance (ecliptic-watcher) eclipticBalanceOf( blockHash: "0x5e82abbe6474caf7b5325022db1d1287ce352488b303685493289770484f54f4" contractAddress: "0x33EeCbf908478C10614626A9D304bfe18B78DD73" _owner: "0x4b5E239C1bbb98d44ea23BC9f8eC7584F54096E8" ) { value } # Check delegation permissions (delegated-sending-watcher) delegatedSendingCanSend( blockHash: "0x2461e78f075e618173c524b5ab4309111001517bb50cfd1b3505aed5433cf5f9" contractAddress: "0xf6b461fE1aD4bd2ce25B23Fe0aff2ac19B3dFA76" _as: 1 _point: 1 ) { value } } ``` ## Understanding Query Parameters All queries require these standard parameters: - **blockHash**: Use `"latest"` for current state, or a specific block hash for historical queries - **contractAddress**: Azimuth contract address (`0x223c067F8CF28ae173EE5CafEa60cA44C335fecB`) - **_point**: The Urbit point number you're querying - **_whose**: Ethereum address when querying by owner ## How It Works ### Data Source The watchers continuously monitor Ethereum smart contracts by connecting to Ethereum RPC endpoint(s), indexing blockchain events and state changes. ### Data Flow 1. **Indexing**: Job runners fetch Ethereum events and blocks from RPC endpoint(s) 2. **Processing**: Events are processed and state changes stored in PostgreSQL databases 3. **Querying**: GraphQL servers provide fast, indexed access to current and historical blockchain state 4. **Gateway**: Unified endpoint routes queries to appropriate specialized watchers ### Storage Each watcher maintains its own PostgreSQL database for efficient querying and data isolation. ## Additional Query Examples ### Query Point Information ```graphql query GetPoint($point: String!) { point(id: $point) { id owner sponsor keyRevisionNumber managementProxy spawnProxy votingProxy transferProxy active escapeRequested escapeRequestedTo } } ``` ## Query Point History ```graphql query GetPointHistory($point: String!) { point(id: $point) { id transfers { timestamp from to blockNumber } spawns { timestamp child blockNumber } } } ``` ## Query Multiple Points ```graphql query GetPoints($owner: String!) { points(where: { owner: $owner }) { id owner sponsor active } } ``` ## Using the GraphQL API ### With curl ```bash # Query Azimuth Watcher curl -X POST https://azimuth-watcher.zenith-test.tlon.systems/graphql \ -H "Content-Type: application/json" \ -d '{ "query": "query { point(id: \"~sampel-palnet\") { owner sponsor } }" }' ``` ### With JavaScript/TypeScript ```javascript const query = ` query GetPoint($point: String!) { point(id: $point) { owner sponsor active } } `; const variables = { point: "~sampel-palnet" }; const response = await fetch('https://azimuth-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://azimuth-watcher.zenith-test.tlon.systems/graphql' ); const query = ` query GetPoint($point: String!) { point(id: $point) { owner sponsor active } } `; const data = await client.request(query, { point: '~sampel-palnet' }); ``` ## 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).