Search…
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
1
query {
2
allTriggers {
3
name
4
}
5
}
Copied!
1
{
2
"data": {
3
"allTriggers": [
4
{
5
"name": "My first trigger"
6
},
7
{
8
"name": "My second trigger"
9
},
10
{
11
"name": "My third trigger"
12
}
13
]
14
}
15
}
Copied!
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
1
query {
2
allTriggers(filter: {name: {eq: "My first trigger"}}) {
3
name
4
}
5
}
Copied!
1
{
2
"data": {
3
"allTriggers": [
4
{
5
"name": "My first trigger"
6
}
7
]
8
}
9
}
Copied!

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:
1
interface Trigger {
2
UUID: UUID!
3
name: String!
4
type: TriggerType!
5
createdAt: Timestamp!
6
updatedAt: Timestamp
7
isActive: Boolean!
8
matchesCount: Int
9
actions: [Action!]!
10
}
Copied!
This means that any type that implements theTrigger interface - Watch transactions, Watch contracts and Watch Events - shares these exact fields with it.

Watch transactions

1
type TransactionsTrigger implements Trigger {
2
UUID: UUID!
3
name: String!
4
type: TriggerType!
5
createdAt: Timestamp!
6
updatedAt: Timestamp
7
isActive: Boolean!
8
matchesCount: Int!
9
actions: [Action!]!
10
11
statement: TransactionsTriggerStatement!
12
}
Copied!

Watch contracts

1
type ContractsTrigger implements Trigger {
2
UUID: UUID!
3
name: String!
4
type: TriggerType!
5
createdAt: Timestamp!
6
updatedAt: Timestamp
7
isActive: Boolean!
8
matchesCount: Int
9
actions: [Action!]!
10
11
isTriggered: Boolean
12
statement: ContractsTriggerStatement!
13
}
Copied!

Watch events

1
type EventsTrigger implements Trigger {
2
UUID: UUID!
3
name: String!
4
type: TriggerType!
5
createdAt: Timestamp!
6
updatedAt: Timestamp
7
isActive: Boolean!
8
matchesCount: Int!
9
actions: [Action!]!
10
11
statement: EventsTriggerStatement!
12
}
Copied!
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
1
{
2
allTriggers {
3
UUID
4
... on EventsTrigger {
5
statement {
6
contract {
7
address
8
abi
9
}
10
filters {
11
method {
12
name
13
}
14
type
15
parameter
16
condition {
17
predicate
18
attribute
19
unit
20
}
21
}
22
}
23
}
24
... on TransactionsTrigger {
25
statement {
26
contract {
27
address
28
abi
29
}
30
filters {
31
type
32
method {
33
name
34
}
35
parameter
36
condition {
37
predicate
38
attribute
39
unit
40
}
41
}
42
}
43
}
44
... on ContractsTrigger {
45
statement {
46
contract {
47
address
48
abi
49
}
50
method {
51
name
52
}
53
inputs
54
outputFilters {
55
returnIndex
56
condition {
57
predicate
58
attribute
59
unit
60
}
61
parameter
62
}
63
}
64
}
65
}
66
}
Copied!
1
{
2
"data": {
3
"allTriggers": [
4
{
5
"UUID": "2ae04b3c-b008-4183-b13f-e23de4f19f13",
6
"statement": {
7
"contract": {
8
"address": "0x080bf510fcbf18b91105470639e9561022937712",
9
"abi": "[{...}]"
10
},
11
"filters": [
12
{
13
"method": {
14
"name": "Fill"
15
},
16
"type": "CheckEventParameter",
17
"parameter": {
18
"name": "makerAddress",
19
"type": "address"
20
},
21
"condition": {
22
"predicate": "Eq",
23
"attribute": "0x49cb7cedb65fcfeabb4d1dcb24d8da202d370eda",
24
"unit": null
25
}
26
},
27
{
28
"method": {
29
"name": "Fill"
30
},
31
"type": "CheckEventParameter",
32
"parameter": {
33
"name": "feeRecipientAddress",
34
"type": "address"
35
},
36
"condition": {
37
"predicate": "Eq",
38
"attribute": "0x8124071f810d533ff63de61d0c98db99eeb99d64",
39
"unit": null
40
}
41
}
42
]
43
}
44
},
45
{
46
"UUID": "be8fb4e4-4355-4321-a5b2-a8f1cc10b582",
47
"statement": {
48
"contract": {
49
"address": "0x15680c612fdde8546c83cf8cc834d2b21a25d20e",
50
"abi": "[{...}]"
51
},
52
"method": {
53
"name": "my_int_array"
54
},
55
"inputs": [
56
{
57
"name": "unnamed-my_int_array-0",
58
"type": "uint256",
59
"value": "100"
60
}
61
],
62
"outputFilters": [
63
{
64
"returnIndex": 1,
65
"condition": {
66
"predicate": "Eq",
67
"attribute": "10",
68
"unit": null
69
},
70
"parameter": {
71
"type": "int64"
72
}
73
}
74
]
75
}
76
},
77
{
78
"UUID": "6228392f-b670-4abb-be71-4b9d9d103c80",
79
"statement": {
80
"contract": {
81
"address": "0x2a0c0dbecc7e4d658f48e01e3fa353f44050c208",
82
"abi": "[{...}]"
83
},
84
"filters": [
85
{
86
"type": "BasicFilter",
87
"method": null,
88
"parameter": {
89
"name": "To"
90
},
91
"condition": {
92
"predicate": "Eq",
93
"attribute": "0x2a0c0dbecc7e4d658f48e01e3fa353f44050c208",
94
"unit": null
95
}
96
},
97
{
98
"type": "CheckFunctionParameter",
99
"method": {
100
"name": "trade"
101
},
102
"parameter": {
103
"index": 1,
104
"name": "tradeValues",
105
"type": "uint256[8]"
106
},
107
"condition": {
108
"predicate": "BiggerThan",
109
"attribute": "8099997953046032478",
110
"unit": null
111
}
112
},
113
{
114
"type": "CheckFunctionParameter",
115
"method": {
116
"name": "trade"
117
},
118
"parameter": {
119
"name": "tradeAddresses",
120
"type": "address[4]"
121
},
122
"condition": {
123
"predicate": "IsIn",
124
"attribute": "0x4a220e6096b25eadb88358cb44068a3248254675",
125
"unit": null
126
}
127
}
128
]
129
}
130
}
131
]
132
}
133
}
Copied!

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:
1
union Response = MailResponse | WebhookResponse | ErrorResponse
Copied!
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
1
query {
2
outcomes {
3
UUID
4
response {
5
... on MailResponse {
6
messageId
7
}
8
... on WebhookResponse {
9
httpCode
10
body
11
}
12
... on ErrorResponse {
13
error
14
}
15
}
16
}
17
}
Copied!
1
{
2
"data": {
3
"outcomes": [
4
{
5
"UUID": "892f6096-5e0d-4fd8-ab12-ec924f0529c7",
6
"response": {
7
"error": "MessageRejected"
8
}
9
},
10
{
11
"UUID": "8e1331d1-3bc3-4c71-b5ef-d00bb6ef2477",
12
"response": {
13
"httpCode": 200,
14
"body": "200 OK"
15
}
16
},
17
{
18
"UUID": "fe406aee-a16c-4d14-bfdc-c14d71c9cb28",
19
"response": {
20
"messageId": "0102016fb5972398-a2cc4344-abd2-4b48-ae29-41beda801466-000000"
21
}
22
}
23
]
24
}
25
}
Copied!