-
Notifications
You must be signed in to change notification settings - Fork 21
Expand file tree
/
Copy pathspectaql.yaml
More file actions
374 lines (310 loc) · 14.2 KB
/
Copy pathspectaql.yaml
File metadata and controls
374 lines (310 loc) · 14.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
spectaql:
logoFile: ./spectaql-theme/b-logo.png
faviconFile: ./spectaql-theme/b-logo.png
targetDir: ./docs/midnight
themeDir: ./spectaql-theme
introspection:
schemaFile: ./midnight-indexer-api.graphql
queryNameStrategy: capitalizeFirst
fieldExpansionDepth: 3
info:
title: Midnight Indexer API
description: |
The Midnight Indexer API exposes a GraphQL API that enables clients to query and subscribe to blockchain data — blocks, transactions, contracts, and wallet-related events — indexed from the Midnight blockchain.
The deployed version of the Midnight Indexer API is **v4**.
For the raw GraphQL schema specification, see the [Midnight Indexer GraphQL Schema](midnight-indexer-api.graphql).
x-introItems:
- title: Quick Start
description: |
Create a Midnight project on [blockfrost.io](https://blockfrost.io) and make your first API call:
```bash
curl -X POST https://midnight-mainnet.blockfrost.io/api/v0 \
-H "project_id: YOUR_PROJECT_ID" \
-H "Content-Type: application/json" \
-d '{"query": "{ block { hash height timestamp } }"}'
```
Response:
```json
{
"data": {
"block": {
"hash": "d193b2686197789ace64962eb3049c5b94c4bbf9b07da04bef034cd75d83afc4",
"height": 192998,
"timestamp": 1770787800000
}
}
}
```
- title: Endpoints
description: |
Blockfrost exposes three Midnight services. Available networks: `mainnet`, `preprod`, `preview`.
| Service | URL |
|---------|-----|
| **Indexer API** | `https://midnight-{network}.blockfrost.io/api/v0` |
| **Indexer WebSocket** | `wss://midnight-{network}.blockfrost.io/api/v0/ws` |
| **Node RPC** | `https://rpc.midnight-{network}.blockfrost.io` |
**Indexer API** — Send GraphQL queries and mutations over HTTP POST. This is the main entry point for fetching blockchain data (blocks, transactions, contracts, DUST status).
**Indexer WebSocket** — Subscribe to real-time events using the `graphql-transport-ws` protocol. Supports block streaming, contract actions, shielded/unshielded transactions, and ledger events.
**Node RPC** — Direct JSON-RPC connection to the Midnight Node for low-level runtime access, wallet providers, and transaction submission. Use it with libraries like [midnight.js](https://github.com/midnightntwrk/midnight-js) that need a node connection.
- title: Authentication
description: |
All requests require a valid project ID. There are two ways to pass it:
**HTTP header**
Include `project_id` as a request header.
```bash
curl -X POST https://midnight-mainnet.blockfrost.io/api/v0 \
-H "project_id: YOUR_PROJECT_ID" \
-H "Content-Type: application/json" \
-d '{"query": "{ block { hash height } }"}'
```
**Query parameter**
Append `?project_id=YOUR_PROJECT_ID` to the endpoint URL. Use this when your client doesn't support setting custom headers (e.g. Midnight.js SDK).
```text
https://midnight-{network}.blockfrost.io/api/v0?project_id=YOUR_PROJECT_ID
wss://midnight-{network}.blockfrost.io/api/v0/ws?project_id=YOUR_PROJECT_ID
https://rpc.midnight-{network}.blockfrost.io?project_id=YOUR_PROJECT_ID
```
Replace `{network}` with `mainnet`, `preprod`, or `preview`.
- title: Request Format
description: |
Send a POST request with a JSON body containing:
* `query` (required): The GraphQL query, mutation, or subscription string
* `variables` (optional): Variables for the GraphQL operation
Example:
```json
{
"query": "query GetBlock($offset: BlockOffset) { block(offset: $offset) { hash height } }",
"variables": { "offset": { "height": 100 } }
}
```
or without variables:
```json
{
"query": "query { block(offset: { height: 100 }) { hash height } }"
}
```
- title: Response Format
description: |
Responses follow the standard GraphQL format:
```json
{
"data": {
"block": {
"hash": "d193b2686197789ace64962eb3049c5b94c4bbf9b07da04bef034cd75d83afc4",
"height": 192998,
"timestamp": 1770787800000
}
}
}
```
On error:
```json
{
"data": null,
"errors": [
{
"message": "Invalid value for argument \"offset.height\" expected type \"Int\"",
"locations": [{ "line": 1, "column": 15 }],
"path": ["block"]
}
]
}
```
- title: HTTP Query Examples
description: |
**Query the latest block:**
```bash
curl -X POST https://midnight-mainnet.blockfrost.io/api/v0 \
-H "project_id: YOUR_PROJECT_ID" \
-H "Content-Type: application/json" \
-d '{"query": "{ block { hash height timestamp author transactions { hash } } }"}'
```
**Query a block by height:**
```bash
curl -X POST https://midnight-mainnet.blockfrost.io/api/v0 \
-H "project_id: YOUR_PROJECT_ID" \
-H "Content-Type: application/json" \
-d '{"query": "{ block(offset: { height: 3 }) { hash height protocolVersion timestamp transactions { hash } } }"}'
```
**Query transactions by hash:**
```bash
curl -X POST https://midnight-mainnet.blockfrost.io/api/v0 \
-H "project_id: YOUR_PROJECT_ID" \
-H "Content-Type: application/json" \
-d '{"query": "{ transactions(offset: { hash: \"YOUR_TX_HASH\" }) { hash protocolVersion fees { paidFees estimatedFees } block { height hash } } }"}'
```
**Query DUST generation status:**
```bash
curl -X POST https://midnight-mainnet.blockfrost.io/api/v0 \
-H "project_id: YOUR_PROJECT_ID" \
-H "Content-Type: application/json" \
-d '{"query": "{ dustGenerationStatus(cardanoRewardAddresses: [\"YOUR_CARDANO_REWARD_ADDRESS\"]) { cardanoRewardAddress dustAddress registered nightBalance generationRate currentCapacity } }"}'
```
**Query contract actions:**
```bash
curl -X POST https://midnight-mainnet.blockfrost.io/api/v0 \
-H "project_id: YOUR_PROJECT_ID" \
-H "Content-Type: application/json" \
-d '{"query": "{ contractAction(address: \"YOUR_CONTRACT_ADDRESS\") { address state transaction { hash } unshieldedBalances { tokenType amount } } }"}'
```
- title: WebSocket Subscriptions
description: |
Subscriptions use a WebSocket connection following the GraphQL over WebSocket protocol.
Most subscriptions accept an optional `offset` parameter, allowing you to resume from a specific block height or transaction hash instead of starting from the tip. This is useful for catching up after a reconnect without re-processing events you've already seen.
**Connecting with `websocat`:**
```bash
websocat wss://midnight-mainnet.blockfrost.io/api/v0/ws \
--protocol "graphql-transport-ws" \
-H "project_id: YOUR_PROJECT_ID"
```
**Step 1 — Initialize the connection:**
After connecting, send a `connection_init` message:
```json
{"type": "connection_init"}
```
The server responds with:
```json
{"type": "connection_ack"}
```
**Step 2 — Send a subscription:**
Once acknowledged, send a `subscribe` message with your GraphQL subscription query:
```json
{
"id": "1",
"type": "subscribe",
"payload": {
"query": "subscription { blocks { hash height timestamp transactions { hash } } }"
}
}
```
**Step 3 — Receive events:**
The server pushes `next` messages whenever new data is available:
```json
{
"id": "1",
"type": "next",
"payload": {
"data": {
"blocks": {
"hash": "d193b2686197789ace64962eb3049c5b94c4bbf9b07da04bef034cd75d83afc4",
"height": 192998,
"timestamp": 1770787800000,
"transactions": []
}
}
}
}
```
**Connecting from JavaScript:**
```javascript
const url = "wss://midnight-mainnet.blockfrost.io/api/v0/ws?project_id=YOUR_PROJECT_ID";
const ws = new WebSocket(url, "graphql-transport-ws");
ws.onopen = () => {
ws.send(JSON.stringify({ type: "connection_init" }));
};
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type === "connection_ack") {
ws.send(
JSON.stringify({
id: "1",
type: "subscribe",
payload: {
query: "subscription { blocks { hash height timestamp } }",
},
})
);
}
if (msg.type === "next") {
console.log("New block:", msg.payload.data);
}
};
```
- title: Query Limits
description: |
The server may apply limitations to queries:
* `max-depth`: Maximum nesting depth
* `max-fields`: Maximum number of fields
* `timeout`: Query execution timeout
* `complexity`: Query complexity cost
Requests exceeding limits return errors:
```json
{
"data": null,
"errors": [{ "message": "Query has too many fields: 20. Max fields: 10." }]
}
```
- title: Pagination with Offsets
description: |
Many queries support offsets for pagination:
**BlockOffset** (oneOf — provide exactly one):
* `hash`: Hex-encoded block hash
* `height`: Block height number
**TransactionOffset** (oneOf — provide exactly one):
* `hash`: Hex-encoded transaction hash
* `identifier`: Hex-encoded transaction identifier
**ContractActionOffset** (oneOf — provide exactly one):
* `blockOffset`: A BlockOffset
* `transactionOffset`: A TransactionOffset
If no offset is provided, the latest result is returned.
- title: Shielded Transactions
description: |
Shielded transactions are at the core of Midnight's privacy model. Because transaction data is encrypted on-chain, the indexer needs a **viewing key** to determine which transactions are relevant to a specific wallet.
The `connect` mutation establishes a server-side session for a given viewing key. The indexer uses this key to scan the chain and filter shielded transactions relevant to that wallet. It returns a **session ID** used to authenticate the `shieldedTransactions` subscription.
When you no longer need to monitor shielded transactions for a wallet, call the `disconnect` mutation with the session ID to end the session and free server-side resources.
**Step 1 — Connect with a viewing key:**
```bash
curl -X POST https://midnight-mainnet.blockfrost.io/api/v0 \
-H "project_id: YOUR_PROJECT_ID" \
-H "Content-Type: application/json" \
-d '{"query": "mutation { connect(viewingKey: \"YOUR_VIEWING_KEY\") }"}'
```
Response:
```json
{
"data": {
"connect": "SESSION_ID_HEX"
}
}
```
The viewing key can be in Bech32m format (preferred, e.g. `mn_shield-esk1...`) or hex.
**Step 2 — Subscribe to shielded transactions:**
Using the session ID from the `connect` mutation, subscribe via WebSocket:
```json
{
"id": "1",
"type": "subscribe",
"payload": {
"query": "subscription($sid: HexEncoded!) { shieldedTransactions(sessionId: $sid, sendProgressUpdates: true) { ... on ViewingUpdate { index update { ... on RelevantTransaction { transaction { hash } } } } ... on ShieldedTransactionsProgress { highestIndex highestRelevantIndex highestRelevantWalletIndex } } }",
"variables": { "sid": "SESSION_ID_HEX" }
}
}
```
The subscription emits two event types:
* `ViewingUpdate` — contains relevant transactions and Merkle tree updates for the wallet
* `ShieldedTransactionsProgress` — reports sync progress (`highestIndex`, `highestRelevantIndex`, `highestRelevantWalletIndex`), useful for showing progress in a UI. Controlled by the `sendProgressUpdates` parameter (default: `true`).
**Step 3 — Disconnect when done:**
```bash
curl -X POST https://midnight-mainnet.blockfrost.io/api/v0 \
-H "project_id: YOUR_PROJECT_ID" \
-H "Content-Type: application/json" \
-d '{"query": "mutation { disconnect(sessionId: \"SESSION_ID_HEX\") }"}'
```
- title: Other Subscriptions
description: |
Besides `blocks` and `shieldedTransactions`, the following subscriptions are available:
* `contractActions(address: HexEncoded!, offset: BlockOffset)` — real-time contract events (deploys, calls, updates) for a specific contract address
* `unshieldedTransactions(address: UnshieldedAddress!, transactionId: Int)` — unshielded transaction events for an address, with optional resume from a specific transaction ID
* `dustLedgerEvents(id: Int)` — DUST ledger state changes (initial UTXOs, generation time updates, spend processing, parameter changes)
* `zswapLedgerEvents(id: Int)` — zswap ledger state changes
- title: Resources
description: |
For more information about the Midnight Indexer API, see the [official Midnight documentation](https://docs.midnight.network/api-reference/midnight-indexer).
servers:
- url: https://midnight-mainnet.blockfrost.io/api/v0
description: Midnight Mainnet
production: true
headers:
- name: project_id
example: YOUR_PROJECT_ID
comment: Your Blockfrost project ID for Midnight Mainnet