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
Response
Query
query {
allTriggers {
name
}
}
Response
{
"data": {
"allTriggers": [
{
"name": "My first trigger"
},
{
"name": "My second trigger"
},
{
"name": "My third trigger"
}
]
}
}

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
Response
Query
query {
allTriggers(filter: {name: {eq: "My first trigger"}}) {
name
}
}
Response
{
"data": {
"allTriggers": [
{
"name": "My first trigger"
}
]
}
}

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:

Query
Response
Query
{
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
}
}
}
}
}
Response
{
"data": {
"allTriggers": [
{
"UUID": "2ae04b3c-b008-4183-b13f-e23de4f19f13",
"statement": {
"contract": {
"address": "0x080bf510fcbf18b91105470639e9561022937712",
"abi": "[{...}]"
},
"filters": [
{
"method": {
"name": "Fill"
},
"type": "CheckEventParameter",
"parameter": {
"name": "makerAddress",
"type": "address"
},
"condition": {
"predicate": "Eq",
"attribute": "0x49cb7cedb65fcfeabb4d1dcb24d8da202d370eda",
"unit": null
}
},
{
"method": {
"name": "Fill"
},
"type": "CheckEventParameter",
"parameter": {
"name": "feeRecipientAddress",
"type": "address"
},
"condition": {
"predicate": "Eq",
"attribute": "0x8124071f810d533ff63de61d0c98db99eeb99d64",
"unit": null
}
}
]
}
},
{
"UUID": "be8fb4e4-4355-4321-a5b2-a8f1cc10b582",
"statement": {
"contract": {
"address": "0x15680c612fdde8546c83cf8cc834d2b21a25d20e",
"abi": "[{...}]"
},
"method": {
"name": "my_int_array"
},
"inputs": [
{
"name": "unnamed-my_int_array-0",
"type": "uint256",
"value": "100"
}
],
"outputFilters": [
{
"returnIndex": 1,
"condition": {
"predicate": "Eq",
"attribute": "10",
"unit": null
},
"parameter": {
"type": "int64"
}
}
]
}
},
{
"UUID": "6228392f-b670-4abb-be71-4b9d9d103c80",
"statement": {
"contract": {
"address": "0x2a0c0dbecc7e4d658f48e01e3fa353f44050c208",
"abi": "[{...}]"
},
"filters": [
{
"type": "BasicFilter",
"method": null,
"parameter": {
"name": "To"
},
"condition": {
"predicate": "Eq",
"attribute": "0x2a0c0dbecc7e4d658f48e01e3fa353f44050c208",
"unit": null
}
},
{
"type": "CheckFunctionParameter",
"method": {
"name": "trade"
},
"parameter": {
"index": 1,
"name": "tradeValues",
"type": "uint256[8]"
},
"condition": {
"predicate": "BiggerThan",
"attribute": "8099997953046032478",
"unit": null
}
},
{
"type": "CheckFunctionParameter",
"method": {
"name": "trade"
},
"parameter": {
"name": "tradeAddresses",
"type": "address[4]"
},
"condition": {
"predicate": "IsIn",
"attribute": "0x4a220e6096b25eadb88358cb44068a3248254675",
"unit": null
}
}
]
}
}
]
}
}

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
Response
Query
query {
outcomes {
UUID
response {
... on MailResponse {
messageId
}
... on WebhookResponse {
httpCode
body
}
... on ErrorResponse {
error
}
}
}
}
Response
{
"data": {
"outcomes": [
{
"UUID": "892f6096-5e0d-4fd8-ab12-ec924f0529c7",
"response": {
"error": "MessageRejected"
}
},
{
"UUID": "8e1331d1-3bc3-4c71-b5ef-d00bb6ef2477",
"response": {
"httpCode": 200,
"body": "200 OK"
}
},
{
"UUID": "fe406aee-a16c-4d14-bfdc-c14d71c9cb28",
"response": {
"messageId": "0102016fb5972398-a2cc4344-abd2-4b48-ae29-41beda801466-000000"
}
}
]
}
}

‚Äč