Remove unnecessary info and update examples
This commit is contained in:
parent
d796dde1a8
commit
2f87f3c7ea
336
README.md
336
README.md
@ -1,10 +1,10 @@
|
||||
# azimuth-watcher-ts
|
||||
|
||||
A comprehensive blockchain indexing and querying system for [Azimuth](https://developers.urbit.org/reference/azimuth/azimuth), Urbit's identity layer on Ethereum. This system monitors multiple Ethereum smart contracts that make up the Azimuth PKI and provides a unified GraphQL API for querying Urbit identity information.
|
||||
A comprehensive blockchain indexing and querying system for [Azimuth](https://docs.urbit.org/system/identity), Urbit's identity layer on Ethereum. This system monitors multiple Ethereum smart contracts that make up the Azimuth PKI and provides a unified GraphQL API for querying Urbit identity information.
|
||||
|
||||
## What is Azimuth?
|
||||
|
||||
Azimuth is Urbit's public key infrastructure (PKI) that lives on Ethereum. It's a set of smart contracts that manage Urbit identities called "points" (similar to usernames), their ownership, cryptographic keys, and hierarchical relationships. Each Urbit identity is represented as an NFT on Ethereum, making it decentralized and censorship-resistant.
|
||||
Azimuth is Urbit's public key infrastructure (PKI) that lives on Ethereum. It's a set of smart contracts that manage Urbit identities called "points" (similar to usernames), their ownership, cryptographic keys, and hierarchical relationships. By storing identity data on Ethereum, the system is decentralized and censorship-resistant.
|
||||
|
||||
## What are Blockchain Watchers?
|
||||
|
||||
@ -41,45 +41,33 @@ The **azimuth-watcher** is the primary service for querying Urbit identity data.
|
||||
|
||||
```bash
|
||||
# Check who owns a specific Urbit point
|
||||
# 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
|
||||
--data-raw '{"query":"{ azimuthGetOwner(blockHash: \"latest\", contractAddress: \"0x223c067F8CF28ae173EE5CafEa60cA44C335fecB\", _point: 1234) { value } }"}' \
|
||||
| jq
|
||||
|
||||
# Response:
|
||||
# {
|
||||
# "data": {
|
||||
# "azimuthGetOwner": {
|
||||
# "value": "0x4b22764F2Db640aB4d0Ecfd0F84344F3CB5C3715"
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
```
|
||||
|
||||
#### 2. Get Cryptographic Keys for a Point
|
||||
|
||||
```bash
|
||||
# Get encryption and authentication keys for networking
|
||||
# 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
|
||||
--data-raw '{"query":"{ azimuthGetKeys(blockHash: \"latest\", contractAddress: \"0x223c067F8CF28ae173EE5CafEa60cA44C335fecB\", _point: 58213) { value { encryptionKey: value0 authenticationKey: value1 cryptoSuiteVersion: value2 keyRevisionNumber: value3 } } }"}' \
|
||||
| jq
|
||||
|
||||
# Example Response:
|
||||
# Response:
|
||||
# {
|
||||
# "data": {
|
||||
# "azimuthGetKeys": {
|
||||
@ -98,34 +86,132 @@ curl 'https://azimuth.dev.vdb.to/graphql' \
|
||||
|
||||
```bash
|
||||
# Check if a point is active (booted) and has a sponsor
|
||||
# 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
|
||||
--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:
|
||||
# {
|
||||
# "data": {
|
||||
# "azimuthIsActive": {
|
||||
# "value": true
|
||||
# },
|
||||
# "azimuthHasSponsor": {
|
||||
# "value": true
|
||||
# },
|
||||
# "azimuthGetSponsor": {
|
||||
# "value": "210"
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
```
|
||||
|
||||
#### 4. Get All Points Owned by an Address
|
||||
|
||||
```bash
|
||||
# Find all Urbit points owned by an Ethereum address
|
||||
# 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
|
||||
--data-raw '{"query":"{ azimuthGetOwnedPoints(blockHash: \"latest\", contractAddress: \"0x223c067F8CF28ae173EE5CafEa60cA44C335fecB\", _whose: \"0x1234567890123456789012345678901234567890\") { value } }"}' \
|
||||
| jq
|
||||
|
||||
# Response:
|
||||
# {
|
||||
# "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
|
||||
@ -137,158 +223,22 @@ All queries require these standard parameters:
|
||||
- **`_point`**: The Urbit point number you're querying
|
||||
- **`_whose`**: Ethereum address when querying by owner
|
||||
|
||||
## Available Query Types
|
||||
## How It Works
|
||||
|
||||
### Azimuth Watcher (Core Identity Operations)
|
||||
### Data Source
|
||||
|
||||
**Point Ownership & Information:**
|
||||
- `azimuthGetOwner` - Get point owner address
|
||||
- `azimuthGetOwnedPoints` - Get all points owned by an address
|
||||
- `azimuthIsActive` - Check if point is activated
|
||||
- `azimuthIsLive` - Check if point is online
|
||||
|
||||
**Cryptographic Keys:**
|
||||
- `azimuthGetKeys` - Get encryption/authentication keys
|
||||
- `azimuthGetKeyRevisionNumber` - Get key version number
|
||||
|
||||
**Sponsorship Hierarchy:**
|
||||
- `azimuthGetSponsor` - Get point's sponsor
|
||||
- `azimuthGetSponsoring` - Get points sponsored by a point
|
||||
- `azimuthHasSponsor` - Check if point has sponsor
|
||||
|
||||
**Proxies & Permissions:**
|
||||
- `azimuthGetManagementProxy` - Get management proxy address
|
||||
- `azimuthCanManage` - Check management permissions
|
||||
- `azimuthGetSpawnProxy` - Get spawn proxy address
|
||||
- `azimuthCanSpawnAs` - Check spawn permissions
|
||||
|
||||
### Other Watchers
|
||||
|
||||
**Censures** - Reputation system queries with prefix `censures`
|
||||
**Claims** - Metadata and claims queries with prefix `claims`
|
||||
**Ecliptic** - Galaxy operations queries with prefix `ecliptic`
|
||||
**Polls** - Governance voting queries with prefix `polls`
|
||||
**Star Release** - Token distribution queries with prefixes `linearStarRelease` and `conditionalStarRelease`
|
||||
**Delegated Sending** - Delegation queries with prefix `delegatedSending`
|
||||
|
||||
### Multi-Watcher Query Example
|
||||
|
||||
```graphql
|
||||
{
|
||||
# Check point status (azimuth-watcher)
|
||||
azimuthIsActive(blockHash: "latest", contractAddress: "0x223c067F8CF28ae173EE5CafEa60cA44C335fecB", _point: 1) {
|
||||
value
|
||||
}
|
||||
|
||||
# Check censure count (censures-watcher)
|
||||
censuresGetCensuredByCount(blockHash: "latest", contractAddress: "0x325f68d32BdEe6Ed86E7235ff2480e2A433D6189", _who: 1) {
|
||||
value
|
||||
}
|
||||
|
||||
# Find a claim (claims-watcher)
|
||||
claimsFindClaim(blockHash: "latest", contractAddress: "0xe7e7f69b34D7d9Bd8d61Fb22C33b22708947971A", _whose: 1234, _protocol: "text", _claim: "hello world") {
|
||||
value
|
||||
}
|
||||
}
|
||||
|
||||
## Real-time Updates
|
||||
|
||||
Subscribe to blockchain events in real-time:
|
||||
|
||||
```graphql
|
||||
subscription {
|
||||
onEvent {
|
||||
event {
|
||||
__typename
|
||||
... on OwnerChangedEvent {
|
||||
point
|
||||
owner
|
||||
}
|
||||
... on ActivatedEvent {
|
||||
point
|
||||
}
|
||||
... on ChangedKeysEvent {
|
||||
point
|
||||
encryptionKey
|
||||
authenticationKey
|
||||
}
|
||||
}
|
||||
block {
|
||||
hash
|
||||
number
|
||||
timestamp
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Development Setup
|
||||
|
||||
### Prerequisites
|
||||
- Node.js 16+
|
||||
- PostgreSQL database
|
||||
- Ethereum RPC endpoint (or ipld-eth-server)
|
||||
|
||||
### Quick Start
|
||||
|
||||
1. **Clone and install dependencies:**
|
||||
```bash
|
||||
git clone https://github.com/cerc-io/azimuth-watcher-ts.git
|
||||
cd azimuth-watcher-ts
|
||||
yarn install
|
||||
```
|
||||
|
||||
2. **Build all packages:**
|
||||
```bash
|
||||
yarn build
|
||||
```
|
||||
|
||||
3. **Configure environment:**
|
||||
- Copy `packages/azimuth-watcher/environments/local.toml` and update database/RPC settings
|
||||
- Set up PostgreSQL databases for each watcher
|
||||
|
||||
4. **Start the azimuth-watcher:**
|
||||
```bash
|
||||
cd packages/azimuth-watcher
|
||||
yarn server:dev # GraphQL server
|
||||
yarn job-runner:dev # Blockchain indexer (separate terminal)
|
||||
```
|
||||
|
||||
5. **Start the gateway server (optional):**
|
||||
```bash
|
||||
cd packages/gateway-server
|
||||
yarn server:dev
|
||||
```
|
||||
|
||||
### Commands
|
||||
|
||||
**Build and lint:**
|
||||
```bash
|
||||
yarn build # Build all packages
|
||||
yarn lint # Lint with zero warnings tolerance
|
||||
```
|
||||
|
||||
**Individual watcher operations:**
|
||||
```bash
|
||||
yarn server:dev # Development GraphQL server
|
||||
yarn job-runner:dev # Event processing worker
|
||||
yarn fill # Backfill historical data
|
||||
yarn reset # Reset watcher state
|
||||
yarn checkpoint # Create state checkpoint
|
||||
```
|
||||
|
||||
## Architecture Details
|
||||
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 continuously fetch Ethereum events and blocks
|
||||
2. **Processing**: Events are processed and state changes stored in PostgreSQL
|
||||
3. **Querying**: GraphQL servers provide indexed data with historical query support
|
||||
|
||||
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
|
||||
- State is checkpointed periodically for recovery
|
||||
- IPLD (Content-addressed storage) support for cryptographic proofs
|
||||
|
||||
Each watcher maintains its own PostgreSQL database for efficient querying and data isolation.
|
||||
|
||||
## Generate Watchers
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user