Skip to content

Latest commit

 

History

History
217 lines (185 loc) · 6 KB

azimuth-watcher.md

File metadata and controls

217 lines (185 loc) · 6 KB

Azimuth Watcher

Azimuth is the public-key infrastructure used for Urbit identities, deployed as smart contracts on Ethereum. For a deep dive, the official documentation has an in-depth reference.

It currently relies on events from Infura (e.g., via eth-mainnet.urbit.org), as seen in this diagram:

urbit-infura

Ideally, this core component of the Urbit stack would not rely on centralized entities. Additionally, events are not verifiable, which defeats the purpose of certain applications that rely on them.

The problem of "getting data from Ethereum" is not unique to Urbit and plagues nearly all applications that rely on blockchain data. Users and Dapp developers either run a full archive node (tricky and expensive) or rely on centralized service providers (easy and expensive). This is one reason why Laconic created the watcher framework, which significantly reduces the cost of reading and verifying blockchain data. This framework was used to create the Azimuth Watcher, which provides a GraphQL interface for querying the Azimuth contracts' state.

Usage

The Azimuth Watcher is open source (see below) but requires good hardware. It is here hosted for your convenience:

Queries

  • range can be maximum 1000 blocks
  • includes full history from contract genesis

Example query from contract genesis

{
  azimuthEventsInRange(fromBlockNumber: 
6784880, toBlockNumber: 
6785880) {
    block {
      hash
      timestamp
    }
    event {
      ... on OwnerChangedEvent {
        __typename
        owner
        point
      }
      ... on ActivatedEvent {
        __typename
        point
      }
      ... on SpawnedEvent {
        __typename
        child
      }
    }
    contract
  }
}

Recent query

{
  azimuthEventsInRange(fromBlockNumber: 
18664121, toBlockNumber: 
18664122) {
    block {
      hash
      timestamp
    }
    event {
      ... on OwnerChangedEvent {
        __typename
        owner
        point
      }
      ... on ActivatedEvent {
        __typename
        point
      }
      ... on SpawnedEvent {
        __typename
        child
      }
    }
    contract
  }
}

Websocket Subscriptions

With Console

go to: https://azimuth.dev.vdb.to/azimuth/graphql

try:

 subscription MySubscription {
    onEvent {
      contract
      event {
        ... on OwnerChangedEvent {
          owner
          point
        }
        __typename
      }
      proof {
        data
      }
    }
  }

In an app

in, e.g., azimuth.js:

// Reference: https://github.com/enisdenjo/graphql-ws/tree/v5.12.0#use-the-client
const { createClient } = require('graphql-ws');
const WebSocket = require('ws');

const client = createClient({
  url: 'wss://azimuth.dev.vdb.to/azimuth/graphql',
  webSocketImpl: WebSocket
});

// subscription
(async () => {
  const onNext = (value) => {
    /* handle incoming values */
    console.log('Received new data:', JSON.stringify(value, null, 2));
  };

  let unsubscribe = () => {
    /* complete the subscription */
    console.log('subscription completed')
  };

  const query = `
  subscription MySubscription {
    onEvent {
      contract
      event {
        ... on OwnerChangedEvent {
          owner
          point
        }
        __typename
      }
    }
  }
  `;

  try {
    await new Promise((resolve, reject) => {
      unsubscribe = client.subscribe(
        { query },
        {
          next: onNext,
          error: reject,
          complete: resolve,
        },
      );
    });
  } catch (err) {
    console.error(err);
  }
})();

then run:

node azimuth.js

example responses:

Received new data: {
  "data": {
    "onEvent": {
      "contract": "0x223c067F8CF28ae173EE5CafEa60cA44C335fecB",
      "event": {
        "owner": "0xCfB830a6ffBC26e847ec40533e102528F7F9D345",
        "point": "2658108823",
        "__typename": "OwnerChangedEvent"
      }
    }
  }
}
Received new data: {
  "data": {
    "onEvent": {
      "contract": "0x223c067F8CF28ae173EE5CafEa60cA44C335fecB",
      "event": {
        "__typename": "BrokeContinuityEvent"
      }
    }
  }
}
Received new data: {
  "data": {
    "onEvent": {
      "contract": "0x223c067F8CF28ae173EE5CafEa60cA44C335fecB",
      "event": {
        "__typename": "ChangedKeysEvent"
      }
    }
  }
}

DIY

  • View the source code here.
  • Use Stack Orchestrator to run the Azimuth Watcher stack.

Future Work

This initial implementation was funded retroactively by the Urbit Foundation. Additional funding is available for a Hoon developer to integrate this source of Azimuth data as an option when running UrbitOS. Contact ~labtul-moltev if you are interested in tackling this task.