Queries

How to fetch data from HAL.

In a nutshell, GraphQL is about asking for specific objects' attributes.

HAL objects are described here. Each object can be queried by GraphQL, so that using a simple query it is possible to fetch specific fields for each object. For example, if you want to get the name field for all triggers, the following request can be used:

query {
  allTriggers {
    name
  }
}

The query response can be further refined by supplying filter and orderBy arguments. For example, for the Trigger object, you can use this query to get a specific record:

query {
  allTriggers(filter: {name: {eq: "My first trigger"}}) {
    name
  }
}

Interfaces

Before you can start using GraphQL queries, you need to get familiar with the concept of interface.

Like many type systems, GraphQL supports interfaces. An Interface is an abstract type that includes a certain set of fields that a type must provide to implement the interface.

For example, in HAL every trigger must implement the Trigger interface:

interface Trigger {
  UUID: UUID!
  name: String!
  type: TriggerType!
  createdAt: Timestamp!
  updatedAt: Timestamp
  isActive: Boolean!
  matchesCount: Int
  actions: [Action!]!
}

This means that any type that implements theTrigger interface - Watch transactions, Watch contracts and Watch Events - shares these exact fields with it.

Watch transactions

type TransactionsTrigger implements Trigger {
  UUID: UUID!
  name: String!
  type: TriggerType!
  createdAt: Timestamp!
  updatedAt: Timestamp
  isActive: Boolean!
  matchesCount: Int!
  actions: [Action!]!
  
  statement: TransactionsTriggerStatement!
}

Watch contracts

type ContractsTrigger implements Trigger {
  UUID: UUID!
  name: String!
  type: TriggerType!
  createdAt: Timestamp!
  updatedAt: Timestamp
  isActive: Boolean!
  matchesCount: Int
  actions: [Action!]!
  
  isTriggered: Boolean
  statement: ContractsTriggerStatement!
}

Watch events

type EventsTrigger implements Trigger {
  UUID: UUID!
  name: String!
  type: TriggerType!
  createdAt: Timestamp!
  updatedAt: Timestamp
  isActive: Boolean!
  matchesCount: Int!
  actions: [Action!]!
  
  statement: EventsTriggerStatement!
}

On top of providing a concrete type for all Trigger interface's attributes, these types also have their own specific fields, like isTriggered and statement, that are specific to that particular type of trigger.

HAL interfaces are:

  • Trigger

  • Match

  • Action

How to query an interface

To ask for a field on a specific object type, you need to use an inline fragment:

{
  allTriggers {
    UUID
    ... on EventsTrigger {
      statement {
        contract {
          address
          abi
        }
        filters {
          method {
            name
          }
          type
          parameter
          condition {
            predicate
            attribute
            unit
          }
        }
      }
    }
    ... on TransactionsTrigger {
      statement {
        contract {
          address
          abi
        }
        filters {
          type
          method {
            name
          }
          parameter
          condition {
            predicate
            attribute
            unit
          }
        }
      }
    }
    ... on ContractsTrigger {
      statement {
        contract {
          address
          abi
        }
        method {
          name
        }
        inputs
        outputFilters {
          returnIndex
          condition {
            predicate
            attribute
            unit
          }
          parameter
        }
      }
    }
  }
}

Unions

The second concept that you need to be familiar with is that of Union types. Please read here to fully appreciate the difference between interfaces and unions types.

For example, within HAL Outcomes you can find the Respond union type:

union Response = MailResponse | WebhookResponse | ErrorResponse

In HAL there are two union types:

  • response

  • payload

How to query a union type

In this case, if you query a field that returns the Response union type, you need to use a conditional fragment:

query {
  outcomes {
    UUID
    response {
      ... on MailResponse  {
        messageId
      }
      ... on WebhookResponse {
        httpCode
        body
      }
      ... on ErrorResponse {
        error
      }
    }
  }
}

Last updated