@o1-labs/mina-archive-node-graphql 0.0.6 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +92 -268
  3. package/build/src/blockchain/utils.js.map +1 -1
  4. package/build/src/config.js +86 -0
  5. package/build/src/config.js.map +1 -0
  6. package/build/src/db/archive-node-adapter/archive-node-adapter.js +29 -2
  7. package/build/src/db/archive-node-adapter/archive-node-adapter.js.map +1 -1
  8. package/build/src/db/archive-node-adapter/postgres-options.js +35 -0
  9. package/build/src/db/archive-node-adapter/postgres-options.js.map +1 -0
  10. package/build/src/db/sql/best-chain.js +5 -0
  11. package/build/src/db/sql/best-chain.js.map +1 -0
  12. package/build/src/db/sql/events-actions/queries.js +102 -21
  13. package/build/src/db/sql/events-actions/queries.js.map +1 -1
  14. package/build/src/db/sql/verification-key-updates/queries.js +100 -0
  15. package/build/src/db/sql/verification-key-updates/queries.js.map +1 -0
  16. package/build/src/db/sql/zkapp-commands/queries.js +363 -0
  17. package/build/src/db/sql/zkapp-commands/queries.js.map +1 -0
  18. package/build/src/db/sql/zkapp-commands/types.js +2 -0
  19. package/build/src/db/sql/zkapp-commands/types.js.map +1 -0
  20. package/build/src/errors/error.js +4 -1
  21. package/build/src/errors/error.js.map +1 -1
  22. package/build/src/index.js +44 -7
  23. package/build/src/index.js.map +1 -1
  24. package/build/src/resolvers.js +42 -23
  25. package/build/src/resolvers.js.map +1 -1
  26. package/build/src/schema-version.js +2 -0
  27. package/build/src/schema-version.js.map +1 -0
  28. package/build/src/server/cors.js +41 -0
  29. package/build/src/server/cors.js.map +1 -0
  30. package/build/src/server/graceful-shutdown.js +42 -0
  31. package/build/src/server/graceful-shutdown.js.map +1 -0
  32. package/build/src/server/graphql-armor.js +39 -0
  33. package/build/src/server/graphql-armor.js.map +1 -0
  34. package/build/src/server/logger.js +45 -0
  35. package/build/src/server/logger.js.map +1 -0
  36. package/build/src/server/metrics.js +72 -0
  37. package/build/src/server/metrics.js.map +1 -0
  38. package/build/src/server/plugins.js +31 -15
  39. package/build/src/server/plugins.js.map +1 -1
  40. package/build/src/server/rate-limit.js +143 -0
  41. package/build/src/server/rate-limit.js.map +1 -0
  42. package/build/src/server/readiness.js +45 -0
  43. package/build/src/server/readiness.js.map +1 -0
  44. package/build/src/server/request-logging.js +58 -0
  45. package/build/src/server/request-logging.js.map +1 -0
  46. package/build/src/server/server.js +38 -13
  47. package/build/src/server/server.js.map +1 -1
  48. package/build/src/services/actions-service/actions-service.js +26 -15
  49. package/build/src/services/actions-service/actions-service.js.map +1 -1
  50. package/build/src/services/blocks-service/blocks-service.js +10 -9
  51. package/build/src/services/blocks-service/blocks-service.js.map +1 -1
  52. package/build/src/services/network-service/network-service.js +17 -9
  53. package/build/src/services/network-service/network-service.js.map +1 -1
  54. package/build/src/services/verification-key-updates-service/verification-key-updates-service.interface.js +2 -0
  55. package/build/src/services/verification-key-updates-service/verification-key-updates-service.interface.js.map +1 -0
  56. package/build/src/services/verification-key-updates-service/verification-key-updates-service.js +41 -0
  57. package/build/src/services/verification-key-updates-service/verification-key-updates-service.js.map +1 -0
  58. package/build/src/services/zkapp-commands-service/zkapp-commands-service.interface.js +2 -0
  59. package/build/src/services/zkapp-commands-service/zkapp-commands-service.interface.js.map +1 -0
  60. package/build/src/services/zkapp-commands-service/zkapp-commands-service.js +115 -0
  61. package/build/src/services/zkapp-commands-service/zkapp-commands-service.js.map +1 -0
  62. package/build/src/tracing/jaeger-tracing.js +2 -1
  63. package/build/src/tracing/jaeger-tracing.js.map +1 -1
  64. package/build/tests/devnet-dump/action-state-invariants.js +165 -0
  65. package/build/tests/devnet-dump/action-state-invariants.js.map +1 -0
  66. package/build/tests/devnet-dump/devnet-dump.test.js +24 -10
  67. package/build/tests/devnet-dump/devnet-dump.test.js.map +1 -1
  68. package/build/tests/devnet-dump/setup.js +63 -17
  69. package/build/tests/devnet-dump/setup.js.map +1 -1
  70. package/build/tests/integration/action-state-ordering.test.js +139 -0
  71. package/build/tests/integration/action-state-ordering.test.js.map +1 -0
  72. package/build/tests/integration/action-state-setup.js +48 -0
  73. package/build/tests/integration/action-state-setup.js.map +1 -0
  74. package/build/tests/integration/consensus-vs-chain.test.js +81 -0
  75. package/build/tests/integration/consensus-vs-chain.test.js.map +1 -0
  76. package/build/tests/integration/integration.test.js +166 -2
  77. package/build/tests/integration/integration.test.js.map +1 -1
  78. package/build/tests/integration/postgres-timeout.test.js +92 -0
  79. package/build/tests/integration/postgres-timeout.test.js.map +1 -0
  80. package/build/tests/integration/setup.js +58 -1
  81. package/build/tests/integration/setup.js.map +1 -1
  82. package/build/tests/integration/verification-key-setup.js +49 -0
  83. package/build/tests/integration/verification-key-setup.js.map +1 -0
  84. package/build/tests/integration/verification-key-updates.test.js +159 -0
  85. package/build/tests/integration/verification-key-updates.test.js.map +1 -0
  86. package/build/tests/live-api/events.test.js +11 -7
  87. package/build/tests/live-api/events.test.js.map +1 -1
  88. package/build/tests/live-api/networkState.test.js +1 -0
  89. package/build/tests/live-api/networkState.test.js.map +1 -1
  90. package/build/tests/live-network/live-network.test.js +1 -0
  91. package/build/tests/live-network/live-network.test.js.map +1 -1
  92. package/build/tests/resolvers.test.js +65 -37
  93. package/build/tests/resolvers.test.js.map +1 -1
  94. package/build/tests/services/verification-key-updates-service/verification-key-updates-service.test.js +35 -0
  95. package/build/tests/services/verification-key-updates-service/verification-key-updates-service.test.js.map +1 -0
  96. package/build/tests/services/zkapp-commands-service/zkapp-commands-service.test.js +159 -0
  97. package/build/tests/services/zkapp-commands-service/zkapp-commands-service.test.js.map +1 -0
  98. package/build/tests/test-helpers.js +15 -0
  99. package/build/tests/test-helpers.js.map +1 -1
  100. package/build/tests/unit/best-chain-anchor.test.js +70 -0
  101. package/build/tests/unit/best-chain-anchor.test.js.map +1 -0
  102. package/build/tests/unit/config.test.js +106 -0
  103. package/build/tests/unit/config.test.js.map +1 -0
  104. package/build/tests/unit/cors.test.js +95 -0
  105. package/build/tests/unit/cors.test.js.map +1 -0
  106. package/build/tests/unit/error-masking.test.js +119 -0
  107. package/build/tests/unit/error-masking.test.js.map +1 -0
  108. package/build/tests/unit/graceful-shutdown.test.js +99 -0
  109. package/build/tests/unit/graceful-shutdown.test.js.map +1 -0
  110. package/build/tests/unit/graphql-armor.test.js +121 -0
  111. package/build/tests/unit/graphql-armor.test.js.map +1 -0
  112. package/build/tests/unit/logging.test.js +120 -0
  113. package/build/tests/unit/logging.test.js.map +1 -0
  114. package/build/tests/unit/metrics.test.js +114 -0
  115. package/build/tests/unit/metrics.test.js.map +1 -0
  116. package/build/tests/unit/network-service.test.js +66 -0
  117. package/build/tests/unit/network-service.test.js.map +1 -0
  118. package/build/tests/unit/postgres-options.test.js +56 -0
  119. package/build/tests/unit/postgres-options.test.js.map +1 -0
  120. package/build/tests/unit/rate-limit.test.js +271 -0
  121. package/build/tests/unit/rate-limit.test.js.map +1 -0
  122. package/build/tests/unit/readiness.test.js +75 -0
  123. package/build/tests/unit/readiness.test.js.map +1 -0
  124. package/build/tests/unit/schema-nullability.test.js +40 -0
  125. package/build/tests/unit/schema-nullability.test.js.map +1 -0
  126. package/build/tests/unit/schema-version.test.js +48 -0
  127. package/build/tests/unit/schema-version.test.js.map +1 -0
  128. package/build/tests/unit/yoga-http-contract.test.js +30 -0
  129. package/build/tests/unit/yoga-http-contract.test.js.map +1 -0
  130. package/build/tests/unit/zkapp-commands-gating.test.js +38 -0
  131. package/build/tests/unit/zkapp-commands-gating.test.js.map +1 -0
  132. package/build/zkapp/utils.js +2 -0
  133. package/build/zkapp/utils.js.map +1 -1
  134. package/package.json +33 -14
  135. package/schema.graphql +126 -8
  136. package/src/blockchain/types.ts +65 -1
  137. package/src/blockchain/utils.ts +26 -2
  138. package/src/config.ts +133 -0
  139. package/src/db/archive-node-adapter/archive-node-adapter.interface.ts +26 -3
  140. package/src/db/archive-node-adapter/archive-node-adapter.ts +65 -2
  141. package/src/db/archive-node-adapter/postgres-options.ts +90 -0
  142. package/src/db/sql/best-chain.ts +34 -0
  143. package/src/db/sql/events-actions/queries.ts +168 -24
  144. package/src/db/sql/verification-key-updates/queries.ts +132 -0
  145. package/src/db/sql/zkapp-commands/queries.ts +406 -0
  146. package/src/db/sql/zkapp-commands/types.ts +43 -0
  147. package/src/envionment.d.ts +20 -0
  148. package/src/errors/error.ts +17 -1
  149. package/src/index.ts +64 -7
  150. package/src/resolvers-types.ts +311 -24
  151. package/src/resolvers.ts +70 -34
  152. package/src/schema-version.ts +24 -0
  153. package/src/server/cors.ts +97 -0
  154. package/src/server/graceful-shutdown.ts +76 -0
  155. package/src/server/graphql-armor.ts +78 -0
  156. package/src/server/logger.ts +72 -0
  157. package/src/server/metrics.ts +104 -0
  158. package/src/server/plugins.ts +53 -19
  159. package/src/server/rate-limit.ts +274 -0
  160. package/src/server/readiness.ts +78 -0
  161. package/src/server/request-logging.ts +83 -0
  162. package/src/server/server.ts +70 -15
  163. package/src/services/actions-service/actions-service.ts +87 -24
  164. package/src/services/blocks-service/blocks-service.ts +16 -14
  165. package/src/services/network-service/network-service.ts +30 -12
  166. package/src/services/verification-key-updates-service/verification-key-updates-service.interface.ts +9 -0
  167. package/src/services/verification-key-updates-service/verification-key-updates-service.ts +72 -0
  168. package/src/services/zkapp-commands-service/zkapp-commands-service.interface.ts +9 -0
  169. package/src/services/zkapp-commands-service/zkapp-commands-service.ts +181 -0
  170. package/src/tracing/jaeger-tracing.ts +2 -1
  171. package/build/tests/consensus/run-compare.js +0 -40
  172. package/build/tests/consensus/run-compare.js.map +0 -1
  173. package/build/tests/consensus/select-consensus-precomputed.js +0 -80
  174. package/build/tests/consensus/select-consensus-precomputed.js.map +0 -1
  175. package/build/tests/consensus/types.js +0 -15
  176. package/build/tests/consensus/types.js.map +0 -1
@@ -0,0 +1,363 @@
1
+ import { BlockStatusFilter } from '../../../blockchain/types.js';
2
+ function blockRangeCte(dbClient, status, to, from) {
3
+ if (status === BlockStatusFilter.canonical) {
4
+ return dbClient `
5
+ max_height AS (
6
+ SELECT MAX(height) AS value FROM blocks
7
+ ),
8
+ block_range AS (
9
+ SELECT
10
+ b.id,
11
+ b.state_hash,
12
+ b.parent_hash,
13
+ b.height,
14
+ b.global_slot_since_genesis,
15
+ b.global_slot_since_hard_fork,
16
+ b.timestamp,
17
+ b.chain_status,
18
+ b.ledger_hash,
19
+ b.last_vrf_output
20
+ FROM blocks b
21
+ WHERE b.chain_status = 'canonical'
22
+ AND b.height >= ${from}
23
+ AND b.height < ${to}
24
+ )
25
+ `;
26
+ }
27
+ return dbClient `
28
+ RECURSIVE max_height AS (
29
+ SELECT MAX(height) AS value FROM blocks
30
+ ),
31
+ pending_chain AS (
32
+ (
33
+ SELECT
34
+ id,
35
+ state_hash,
36
+ parent_hash,
37
+ parent_id,
38
+ height,
39
+ global_slot_since_genesis,
40
+ global_slot_since_hard_fork,
41
+ timestamp,
42
+ chain_status,
43
+ ledger_hash,
44
+ last_vrf_output
45
+ FROM blocks
46
+ WHERE height = (SELECT value FROM max_height)
47
+ )
48
+ UNION ALL
49
+ SELECT
50
+ b.id,
51
+ b.state_hash,
52
+ b.parent_hash,
53
+ b.parent_id,
54
+ b.height,
55
+ b.global_slot_since_genesis,
56
+ b.global_slot_since_hard_fork,
57
+ b.timestamp,
58
+ b.chain_status,
59
+ b.ledger_hash,
60
+ b.last_vrf_output
61
+ FROM blocks b
62
+ INNER JOIN pending_chain
63
+ ON b.id = pending_chain.parent_id
64
+ AND pending_chain.id <> pending_chain.parent_id
65
+ AND pending_chain.chain_status <> 'canonical'
66
+ ),
67
+ full_chain AS (
68
+ SELECT DISTINCT
69
+ id,
70
+ state_hash,
71
+ parent_id,
72
+ parent_hash,
73
+ height,
74
+ global_slot_since_genesis,
75
+ global_slot_since_hard_fork,
76
+ timestamp,
77
+ chain_status,
78
+ ledger_hash,
79
+ last_vrf_output
80
+ FROM (
81
+ SELECT
82
+ id,
83
+ state_hash,
84
+ parent_id,
85
+ parent_hash,
86
+ height,
87
+ global_slot_since_genesis,
88
+ global_slot_since_hard_fork,
89
+ timestamp,
90
+ chain_status,
91
+ ledger_hash,
92
+ last_vrf_output
93
+ FROM pending_chain
94
+ WHERE height >= ${from}
95
+ AND height < ${to}
96
+ UNION ALL
97
+ SELECT
98
+ id,
99
+ state_hash,
100
+ parent_id,
101
+ parent_hash,
102
+ height,
103
+ global_slot_since_genesis,
104
+ global_slot_since_hard_fork,
105
+ timestamp,
106
+ chain_status,
107
+ ledger_hash,
108
+ last_vrf_output
109
+ FROM blocks b
110
+ WHERE chain_status = 'canonical'
111
+ AND b.height >= ${from}
112
+ AND b.height < ${to}
113
+ ) AS resolved_chain
114
+ ),
115
+ block_range AS (
116
+ SELECT
117
+ b.id,
118
+ b.state_hash,
119
+ b.parent_hash,
120
+ b.height,
121
+ b.global_slot_since_genesis,
122
+ b.global_slot_since_hard_fork,
123
+ b.timestamp,
124
+ b.chain_status,
125
+ b.ledger_hash,
126
+ b.last_vrf_output
127
+ FROM full_chain b
128
+ WHERE 1 = 1
129
+ ${status === BlockStatusFilter.all
130
+ ? dbClient ``
131
+ : dbClient `AND b.chain_status = ${status.toLowerCase()}`}
132
+ )
133
+ `;
134
+ }
135
+ function accountUpdateFilterCtes(dbClient, accountPublicKey, tokenId) {
136
+ if (!accountPublicKey && !tokenId) {
137
+ return dbClient ``;
138
+ }
139
+ return dbClient `
140
+ ,
141
+ matching_account_identifiers AS (
142
+ SELECT ai.id
143
+ FROM account_identifiers ai
144
+ JOIN public_keys pk ON ai.public_key_id = pk.id
145
+ JOIN tokens t ON ai.token_id = t.id
146
+ WHERE 1 = 1
147
+ ${accountPublicKey
148
+ ? dbClient `AND pk.value = ${accountPublicKey}`
149
+ : dbClient ``}
150
+ ${tokenId ? dbClient `AND t.value = ${tokenId}` : dbClient ``}
151
+ ),
152
+ target_account_updates AS (
153
+ SELECT zkau.id AS account_update_id
154
+ FROM matching_account_identifiers mai
155
+ JOIN zkapp_account_update_body zkub
156
+ ON zkub.account_identifier_id = mai.id
157
+ JOIN zkapp_account_update zkau ON zkau.body_id = zkub.id
158
+ )
159
+ `;
160
+ }
161
+ function accountUpdateRowsJoin(dbClient, accountPublicKey, tokenId) {
162
+ if (!accountPublicKey && !tokenId) {
163
+ return dbClient `
164
+ JOIN LATERAL unnest(zkc.zkapp_account_updates_ids)
165
+ WITH ORDINALITY AS account_update_ids(account_update_id, account_update_order) ON true
166
+ JOIN zkapp_account_update zkau ON zkau.id = account_update_ids.account_update_id
167
+ `;
168
+ }
169
+ return dbClient `
170
+ JOIN target_account_updates tau
171
+ ON tau.account_update_id = ANY(zkc.zkapp_account_updates_ids)
172
+ JOIN LATERAL (
173
+ SELECT account_update_ids.account_update_id, account_update_ids.account_update_order
174
+ FROM unnest(zkc.zkapp_account_updates_ids)
175
+ WITH ORDINALITY AS account_update_ids(account_update_id, account_update_order)
176
+ WHERE account_update_ids.account_update_id = tau.account_update_id
177
+ ) account_update_ids ON true
178
+ JOIN zkapp_account_update zkau ON zkau.id = tau.account_update_id
179
+ `;
180
+ }
181
+ export function getZkappCommandsQuery(dbClient, status, to, from, accountPublicKey, tokenId) {
182
+ return dbClient `
183
+ WITH ${blockRangeCte(dbClient, status, to, from)}
184
+ ${accountUpdateFilterCtes(dbClient, accountPublicKey, tokenId)}
185
+ SELECT
186
+ b.id AS block_id,
187
+ b.state_hash,
188
+ b.parent_hash,
189
+ b.height,
190
+ b.global_slot_since_genesis,
191
+ b.global_slot_since_hard_fork,
192
+ b.timestamp,
193
+ b.chain_status,
194
+ b.ledger_hash,
195
+ (SELECT value FROM max_height) - b.height AS distance_from_max_block_height,
196
+ b.last_vrf_output,
197
+ zkc.hash,
198
+ zkc.memo,
199
+ bzkc.sequence_no AS sequence_number,
200
+ fee_payer_pk.value AS fee_payer,
201
+ fpb.fee,
202
+ zkau.id AS account_update_id,
203
+ account_update_ids.account_update_order,
204
+ account_update_pk.value AS public_key,
205
+ t.value AS token_id,
206
+ zkub.authorization_kind,
207
+ zkub.balance_change,
208
+ zkub.increment_nonce,
209
+ zkub.call_depth,
210
+ COALESCE(actions.fields, '[]'::jsonb) AS actions,
211
+ COALESCE(events.fields, '[]'::jsonb) AS events,
212
+ app_state.fields AS app_state,
213
+ account_precondition_state.fields AS account_precondition_state,
214
+ account_precondition_action_state.fields AS account_precondition_action_state,
215
+ account_precondition.proved_state AS account_precondition_proved_state,
216
+ account_precondition.is_new AS account_precondition_is_new,
217
+ network_global_slot_bounds.global_slot_lower_bound AS network_precondition_global_slot_lower_bound,
218
+ network_global_slot_bounds.global_slot_upper_bound AS network_precondition_global_slot_upper_bound
219
+ FROM block_range b
220
+ JOIN blocks_zkapp_commands bzkc
221
+ ON b.id = bzkc.block_id
222
+ AND bzkc.status <> 'failed'
223
+ JOIN zkapp_commands zkc ON bzkc.zkapp_command_id = zkc.id
224
+ JOIN zkapp_fee_payer_body fpb ON zkc.zkapp_fee_payer_body_id = fpb.id
225
+ JOIN public_keys fee_payer_pk ON fpb.public_key_id = fee_payer_pk.id
226
+ ${accountUpdateRowsJoin(dbClient, accountPublicKey, tokenId)}
227
+ JOIN zkapp_account_update_body zkub ON zkau.body_id = zkub.id
228
+ JOIN account_identifiers ai ON zkub.account_identifier_id = ai.id
229
+ JOIN public_keys account_update_pk
230
+ ON ai.public_key_id = account_update_pk.id
231
+ ${accountPublicKey
232
+ ? dbClient `AND account_update_pk.value = ${accountPublicKey}`
233
+ : dbClient ``}
234
+ JOIN tokens t
235
+ ON ai.token_id = t.id
236
+ ${tokenId ? dbClient `AND t.value = ${tokenId}` : dbClient ``}
237
+ LEFT JOIN zkapp_updates update_body ON update_body.id = zkub.update_id
238
+ LEFT JOIN zkapp_states_nullable app_state_rows ON app_state_rows.id = update_body.app_state_id
239
+ LEFT JOIN zkapp_account_precondition account_precondition
240
+ ON account_precondition.id = zkub.zkapp_account_precondition_id
241
+ LEFT JOIN zkapp_states_nullable account_precondition_state_rows
242
+ ON account_precondition_state_rows.id = account_precondition.state_id
243
+ LEFT JOIN zkapp_action_states account_precondition_action_state_rows
244
+ ON account_precondition_action_state_rows.id = account_precondition.action_state_id
245
+ LEFT JOIN zkapp_network_precondition network_precondition
246
+ ON network_precondition.id = zkub.zkapp_network_precondition_id
247
+ LEFT JOIN zkapp_global_slot_bounds network_global_slot_bounds
248
+ ON network_global_slot_bounds.id = network_precondition.global_slot_since_genesis
249
+ LEFT JOIN LATERAL (
250
+ SELECT COALESCE(jsonb_agg(jsonb_build_object('fields', field_array.fields) ORDER BY event_ids.event_order), '[]'::jsonb) AS fields
251
+ FROM zkapp_events action_events
252
+ JOIN LATERAL unnest(action_events.element_ids)
253
+ WITH ORDINALITY AS event_ids(field_array_id, event_order) ON true
254
+ JOIN zkapp_field_array event_field_array ON event_field_array.id = event_ids.field_array_id
255
+ JOIN LATERAL (
256
+ SELECT COALESCE(jsonb_agg(zkf.field ORDER BY field_ids.field_order), '[]'::jsonb) AS fields
257
+ FROM unnest(event_field_array.element_ids)
258
+ WITH ORDINALITY AS field_ids(field_id, field_order)
259
+ JOIN zkapp_field zkf ON zkf.id = field_ids.field_id
260
+ ) field_array ON true
261
+ WHERE action_events.id = zkub.actions_id
262
+ ) actions ON true
263
+ LEFT JOIN LATERAL (
264
+ SELECT COALESCE(jsonb_agg(jsonb_build_object('fields', field_array.fields) ORDER BY event_ids.event_order), '[]'::jsonb) AS fields
265
+ FROM zkapp_events account_update_events
266
+ JOIN LATERAL unnest(account_update_events.element_ids)
267
+ WITH ORDINALITY AS event_ids(field_array_id, event_order) ON true
268
+ JOIN zkapp_field_array event_field_array ON event_field_array.id = event_ids.field_array_id
269
+ JOIN LATERAL (
270
+ SELECT COALESCE(jsonb_agg(zkf.field ORDER BY field_ids.field_order), '[]'::jsonb) AS fields
271
+ FROM unnest(event_field_array.element_ids)
272
+ WITH ORDINALITY AS field_ids(field_id, field_order)
273
+ JOIN zkapp_field zkf ON zkf.id = field_ids.field_id
274
+ ) field_array ON true
275
+ WHERE account_update_events.id = zkub.events_id
276
+ ) events ON true
277
+ LEFT JOIN LATERAL (
278
+ SELECT jsonb_build_object('fields', jsonb_agg(zkf.field ORDER BY state_fields.field_order)) AS fields
279
+ FROM (VALUES
280
+ (0, app_state_rows.element0), (1, app_state_rows.element1),
281
+ (2, app_state_rows.element2), (3, app_state_rows.element3),
282
+ (4, app_state_rows.element4), (5, app_state_rows.element5),
283
+ (6, app_state_rows.element6), (7, app_state_rows.element7),
284
+ (8, app_state_rows.element8), (9, app_state_rows.element9),
285
+ (10, app_state_rows.element10), (11, app_state_rows.element11),
286
+ (12, app_state_rows.element12), (13, app_state_rows.element13),
287
+ (14, app_state_rows.element14), (15, app_state_rows.element15),
288
+ (16, app_state_rows.element16), (17, app_state_rows.element17),
289
+ (18, app_state_rows.element18), (19, app_state_rows.element19),
290
+ (20, app_state_rows.element20), (21, app_state_rows.element21),
291
+ (22, app_state_rows.element22), (23, app_state_rows.element23),
292
+ (24, app_state_rows.element24), (25, app_state_rows.element25),
293
+ (26, app_state_rows.element26), (27, app_state_rows.element27),
294
+ (28, app_state_rows.element28), (29, app_state_rows.element29),
295
+ (30, app_state_rows.element30), (31, app_state_rows.element31)
296
+ ) AS state_fields(field_order, field_id)
297
+ LEFT JOIN zkapp_field zkf ON zkf.id = state_fields.field_id
298
+ WHERE app_state_rows.id IS NOT NULL
299
+ ) app_state ON true
300
+ LEFT JOIN LATERAL (
301
+ SELECT jsonb_build_object('fields', jsonb_agg(zkf.field ORDER BY state_fields.field_order)) AS fields
302
+ FROM (VALUES
303
+ (0, account_precondition_state_rows.element0), (1, account_precondition_state_rows.element1),
304
+ (2, account_precondition_state_rows.element2), (3, account_precondition_state_rows.element3),
305
+ (4, account_precondition_state_rows.element4), (5, account_precondition_state_rows.element5),
306
+ (6, account_precondition_state_rows.element6), (7, account_precondition_state_rows.element7),
307
+ (8, account_precondition_state_rows.element8), (9, account_precondition_state_rows.element9),
308
+ (10, account_precondition_state_rows.element10), (11, account_precondition_state_rows.element11),
309
+ (12, account_precondition_state_rows.element12), (13, account_precondition_state_rows.element13),
310
+ (14, account_precondition_state_rows.element14), (15, account_precondition_state_rows.element15),
311
+ (16, account_precondition_state_rows.element16), (17, account_precondition_state_rows.element17),
312
+ (18, account_precondition_state_rows.element18), (19, account_precondition_state_rows.element19),
313
+ (20, account_precondition_state_rows.element20), (21, account_precondition_state_rows.element21),
314
+ (22, account_precondition_state_rows.element22), (23, account_precondition_state_rows.element23),
315
+ (24, account_precondition_state_rows.element24), (25, account_precondition_state_rows.element25),
316
+ (26, account_precondition_state_rows.element26), (27, account_precondition_state_rows.element27),
317
+ (28, account_precondition_state_rows.element28), (29, account_precondition_state_rows.element29),
318
+ (30, account_precondition_state_rows.element30), (31, account_precondition_state_rows.element31)
319
+ ) AS state_fields(field_order, field_id)
320
+ LEFT JOIN zkapp_field zkf ON zkf.id = state_fields.field_id
321
+ WHERE account_precondition_state_rows.id IS NOT NULL
322
+ ) account_precondition_state ON true
323
+ LEFT JOIN LATERAL (
324
+ SELECT jsonb_build_object('fields', jsonb_agg(zkf.field ORDER BY action_state_fields.field_order)) AS fields
325
+ FROM (VALUES
326
+ (0, account_precondition_action_state_rows.element0),
327
+ (1, account_precondition_action_state_rows.element1),
328
+ (2, account_precondition_action_state_rows.element2),
329
+ (3, account_precondition_action_state_rows.element3),
330
+ (4, account_precondition_action_state_rows.element4)
331
+ ) AS action_state_fields(field_order, field_id)
332
+ LEFT JOIN zkapp_field zkf ON zkf.id = action_state_fields.field_id
333
+ WHERE account_precondition_action_state_rows.id IS NOT NULL
334
+ ) account_precondition_action_state ON true
335
+ ORDER BY b.height, bzkc.sequence_no, account_update_ids.account_update_order;
336
+ `;
337
+ }
338
+ export function getZkappCommandAccountUpdateCountQuery(dbClient, status, to, from, accountPublicKey, tokenId) {
339
+ if (!accountPublicKey && !tokenId) {
340
+ return dbClient `
341
+ WITH ${blockRangeCte(dbClient, status, to, from)}
342
+ SELECT COALESCE(SUM(cardinality(zkc.zkapp_account_updates_ids)), 0)::text AS count
343
+ FROM block_range b
344
+ JOIN blocks_zkapp_commands bzkc
345
+ ON b.id = bzkc.block_id
346
+ AND bzkc.status <> 'failed'
347
+ JOIN zkapp_commands zkc ON bzkc.zkapp_command_id = zkc.id;
348
+ `;
349
+ }
350
+ return dbClient `
351
+ WITH ${blockRangeCte(dbClient, status, to, from)}
352
+ ${accountUpdateFilterCtes(dbClient, accountPublicKey, tokenId)}
353
+ SELECT COUNT(*) AS count
354
+ FROM block_range b
355
+ JOIN blocks_zkapp_commands bzkc
356
+ ON b.id = bzkc.block_id
357
+ AND bzkc.status <> 'failed'
358
+ JOIN zkapp_commands zkc ON bzkc.zkapp_command_id = zkc.id
359
+ JOIN target_account_updates tau
360
+ ON tau.account_update_id = ANY(zkc.zkapp_account_updates_ids);
361
+ `;
362
+ }
363
+ //# sourceMappingURL=queries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queries.js","sourceRoot":"","sources":["../../../../../src/db/sql/zkapp-commands/queries.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../src/db/sql/zkapp-commands/types.ts"],"names":[],"mappings":""}
@@ -1,5 +1,5 @@
1
1
  import { GraphQLError } from 'graphql';
2
- export { throwGraphQLError, throwActionStateError, throwBlockRangeError };
2
+ export { throwGraphQLError, throwActionStateError, throwActionStateOutOfRangeError, throwBlockRangeError, };
3
3
  function throwGraphQLError(message, code, status) {
4
4
  throw new GraphQLError(message, {
5
5
  extensions: {
@@ -11,6 +11,9 @@ function throwGraphQLError(message, code, status) {
11
11
  function throwActionStateError(message) {
12
12
  throwGraphQLError(message, 'ACTION_STATE_NOT_FOUND', 400);
13
13
  }
14
+ function throwActionStateOutOfRangeError(message) {
15
+ throwGraphQLError(message, 'ACTION_STATE_OUT_OF_RANGE', 400);
16
+ }
14
17
  function throwBlockRangeError(message) {
15
18
  throwGraphQLError(message, 'BLOCK_RANGE_ERROR', 400);
16
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"error.js","sourceRoot":"","sources":["../../../src/errors/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,CAAC;AAE1E,SAAS,iBAAiB,CAAC,OAAe,EAAE,IAAa,EAAE,MAAe;IACxE,MAAM,IAAI,YAAY,CAAC,OAAO,EAAE;QAC9B,UAAU,EAAE;YACV,IAAI;YACJ,MAAM;SACP;KACF,CAAC,CAAC;AACL,CAAC;AAED,SAAS,qBAAqB,CAAC,OAAe;IAC5C,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,EAAE,GAAG,CAAC,CAAC;AAC5D,CAAC;AAED,SAAS,oBAAoB,CAAC,OAAe;IAC3C,iBAAiB,CAAC,OAAO,EAAE,mBAAmB,EAAE,GAAG,CAAC,CAAC;AACvD,CAAC"}
1
+ {"version":3,"file":"error.js","sourceRoot":"","sources":["../../../src/errors/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,+BAA+B,EAC/B,oBAAoB,GACrB,CAAC;AAEF,SAAS,iBAAiB,CAAC,OAAe,EAAE,IAAa,EAAE,MAAe;IACxE,MAAM,IAAI,YAAY,CAAC,OAAO,EAAE;QAC9B,UAAU,EAAE;YACV,IAAI;YACJ,MAAM;SACP;KACF,CAAC,CAAC;AACL,CAAC;AAED,SAAS,qBAAqB,CAAC,OAAe;IAC5C,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,EAAE,GAAG,CAAC,CAAC;AAC5D,CAAC;AASD,SAAS,+BAA+B,CAAC,OAAe;IACtD,iBAAiB,CAAC,OAAO,EAAE,2BAA2B,EAAE,GAAG,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,oBAAoB,CAAC,OAAe;IAC3C,iBAAiB,CAAC,OAAO,EAAE,mBAAmB,EAAE,GAAG,CAAC,CAAC;AACvD,CAAC"}
@@ -2,25 +2,62 @@
2
2
  import { buildContext } from './context.js';
3
3
  import { buildServer } from './server/server.js';
4
4
  import { buildPlugins } from './server/plugins.js';
5
+ import { createGracefulShutdown } from './server/graceful-shutdown.js';
6
+ import { assertValidConfig } from './config.js';
7
+ import { logger } from './server/logger.js';
5
8
  const PORT = process.env.PORT || 8080;
9
+ const SHUTDOWN_TIMEOUT_MS = Number(process.env.SHUTDOWN_TIMEOUT_MS) || 20000;
10
+ function withTimeout(label, ms, run) {
11
+ let timer;
12
+ return Promise.race([
13
+ run(),
14
+ new Promise((_, reject) => {
15
+ timer = setTimeout(() => reject(new Error(`${label} timed out after ${ms}ms`)), ms);
16
+ }),
17
+ ])
18
+ .then(() => undefined)
19
+ .finally(() => {
20
+ if (timer !== undefined)
21
+ clearTimeout(timer);
22
+ });
23
+ }
6
24
  (async function main() {
7
25
  try {
26
+ assertValidConfig();
8
27
  const context = await buildContext(process.env.PG_CONN);
9
- const plugins = await buildPlugins();
28
+ const { plugins, provider } = await buildPlugins();
10
29
  const server = buildServer(context, plugins);
11
30
  server.listen(PORT, () => {
12
- console.info(`Server is running on port: ${PORT}`);
31
+ logger.info({ port: PORT }, 'server started');
32
+ });
33
+ const shutdown = createGracefulShutdown({
34
+ timeoutMs: SHUTDOWN_TIMEOUT_MS,
35
+ closeServer: () => new Promise((resolve, reject) => {
36
+ server.close((error) => (error ? reject(error) : resolve()));
37
+ server.closeIdleConnections();
38
+ }),
39
+ closers: [
40
+ () => withTimeout('trace flush', 3000, async () => {
41
+ if (provider)
42
+ await provider.shutdown();
43
+ }),
44
+ () => withTimeout('pg pool close', 5000, () => context.db_client.close()),
45
+ ],
13
46
  });
14
47
  ['SIGINT', 'SIGTERM', 'SIGQUIT'].forEach((signal) => {
15
- process.on(signal, () => server.close());
48
+ process.on(signal, () => void shutdown(signal));
49
+ });
50
+ process.on('uncaughtException', (error) => {
51
+ logger.error({ err: error }, 'uncaught exception');
52
+ void shutdown('uncaughtException', 1);
16
53
  });
17
- server.on('close', async () => {
18
- await context.db_client.close();
19
- process.exit(0);
54
+ process.on('unhandledRejection', (reason) => {
55
+ logger.error({ err: reason }, 'unhandled rejection');
56
+ void shutdown('unhandledRejection', 1);
20
57
  });
21
58
  }
22
59
  catch (error) {
23
- console.error('An error occurred:', error);
60
+ logger.error({ err: error }, 'fatal error during startup');
24
61
  process.exit(1);
25
62
  }
26
63
  })();
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC;AAEtC,CAAC,KAAK,UAAU,IAAI;IAClB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACxD,MAAM,OAAO,GAAG,MAAM,YAAY,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAE7C,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;YACvB,OAAO,CAAC,IAAI,CAAC,8BAA8B,IAAI,EAAE,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;QAEH,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;YAClD,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;YAC5B,MAAM,OAAO,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;YAChC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;QAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -4,11 +4,15 @@ import fs from 'fs';
4
4
  import path from 'path';
5
5
  import { fileURLToPath } from 'url';
6
6
  import { TracingState, setSpanNameFromGraphQLContext, } from './tracing/tracer.js';
7
+ import { parseBoolean } from './config.js';
8
+ import { SCHEMA_VERSION } from './schema-version.js';
7
9
  const __filename = fileURLToPath(import.meta.url);
8
10
  const __dirname = path.dirname(__filename);
9
11
  const schemaPath = path.resolve(__dirname, '../../schema.graphql');
12
+ const ENABLE_ZKAPP_COMMANDS_QUERY = parseBoolean(process.env.ENABLE_ZKAPP_COMMANDS_QUERY);
10
13
  const fullResolvers = {
11
14
  Query: {
15
+ schemaVersion: () => SCHEMA_VERSION,
12
16
  events: async (_, { input }, context) => {
13
17
  const graphQLSpan = setSpanNameFromGraphQLContext(context, 'events.graphql');
14
18
  return context.db_client.getEvents(input, {
@@ -21,6 +25,18 @@ const fullResolvers = {
21
25
  tracingState: new TracingState(graphQLSpan),
22
26
  });
23
27
  },
28
+ verificationKeyUpdates: async (_, { input }, context) => {
29
+ const graphQLSpan = setSpanNameFromGraphQLContext(context, 'verificationKeyUpdates.graphql');
30
+ return context.db_client.getVerificationKeyUpdates(input, {
31
+ tracingState: new TracingState(graphQLSpan),
32
+ });
33
+ },
34
+ zkappCommands: async (_, { input }, context) => {
35
+ const graphQLSpan = setSpanNameFromGraphQLContext(context, 'zkappCommands.graphql');
36
+ return context.db_client.getZkappCommands(input, {
37
+ tracingState: new TracingState(graphQLSpan),
38
+ });
39
+ },
24
40
  networkState: async (_, __, context) => {
25
41
  const graphQLSpan = setSpanNameFromGraphQLContext(context, 'networkState.graphql');
26
42
  return context.db_client.getNetworkState({
@@ -35,33 +51,36 @@ const fullResolvers = {
35
51
  },
36
52
  },
37
53
  };
38
- let resolvers = fullResolvers;
39
- let typeDefs = undefined;
54
+ let enabledQueries = Object.keys(fullResolvers.Query || {});
55
+ const ALWAYS_ENABLED = ['schemaVersion'];
40
56
  if (process.env.ENABLED_QUERIES !== undefined) {
41
- const enabledQueries = process.env.ENABLED_QUERIES.split(',').map((q) => q.trim());
42
- if (enabledQueries.length > 0) {
43
- resolvers = {
44
- Query: Object.fromEntries(Object.entries(fullResolvers.Query || {}).filter(([queryName]) => enabledQueries.includes(queryName))),
45
- };
46
- const typeDefsString = fs.readFileSync(schemaPath, 'utf-8');
47
- const typeDefsAst = parse(typeDefsString);
48
- const modifiedAst = visit(typeDefsAst, {
49
- ObjectTypeDefinition(node) {
50
- if (node.name.value === 'Query') {
51
- return {
52
- ...node,
53
- fields: node.fields?.filter((field) => enabledQueries.includes(field.name.value)),
54
- };
55
- }
56
- return node;
57
- },
58
- });
59
- typeDefs = print(modifiedAst);
60
- }
57
+ enabledQueries = [
58
+ ...ALWAYS_ENABLED,
59
+ ...process.env.ENABLED_QUERIES.split(',').map((q) => q.trim()),
60
+ ];
61
+ }
62
+ if (!ENABLE_ZKAPP_COMMANDS_QUERY) {
63
+ enabledQueries = enabledQueries.filter((queryName) => queryName !== 'zkappCommands');
61
64
  }
65
+ const resolvers = {
66
+ Query: Object.fromEntries(Object.entries(fullResolvers.Query || {}).filter(([queryName]) => enabledQueries.includes(queryName))),
67
+ };
68
+ const typeDefsString = fs.readFileSync(schemaPath, 'utf-8');
69
+ const typeDefsAst = parse(typeDefsString);
70
+ const modifiedAst = visit(typeDefsAst, {
71
+ ObjectTypeDefinition(node) {
72
+ if (node.name.value === 'Query') {
73
+ return {
74
+ ...node,
75
+ fields: node.fields?.filter((field) => enabledQueries.includes(field.name.value)),
76
+ };
77
+ }
78
+ return node;
79
+ },
80
+ });
62
81
  const schema = makeExecutableSchema({
63
82
  resolvers: [resolvers],
64
- typeDefs: typeDefs || fs.readFileSync(schemaPath, 'utf-8'),
83
+ typeDefs: print(modifiedAst),
65
84
  });
66
85
  export { resolvers, schema };
67
86
  //# sourceMappingURL=resolvers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolvers.js","sourceRoot":"","sources":["../../src/resolvers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"resolvers.js","sourceRoot":"","sources":["../../src/resolvers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export const SCHEMA_VERSION = '2.0';
2
+ //# sourceMappingURL=schema-version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-version.js","sourceRoot":"","sources":["../../src/schema-version.ts"],"names":[],"mappings":"AAuBA,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,CAAC"}
@@ -0,0 +1,41 @@
1
+ export { resolveCorsOptions, warnIfCorsDisabled };
2
+ const CORS_METHODS = ['GET', 'POST'];
3
+ const CORS_HEADERS = ['content-type'];
4
+ const corsBase = {
5
+ methods: CORS_METHODS,
6
+ allowedHeaders: CORS_HEADERS,
7
+ credentials: false,
8
+ };
9
+ function resolveCorsOptions(env = process.env) {
10
+ const raw = env.CORS_ORIGIN?.trim();
11
+ if (!raw)
12
+ return false;
13
+ if (raw === '*')
14
+ return { origin: '*', ...corsBase };
15
+ const origins = raw
16
+ .split(',')
17
+ .map((origin) => origin.trim())
18
+ .filter((origin) => origin.length > 0);
19
+ if (origins.length === 0)
20
+ return false;
21
+ for (const origin of origins) {
22
+ if (origin.endsWith('/') ||
23
+ origin !== origin.toLowerCase() ||
24
+ origin.includes('*')) {
25
+ console.warn(`[cors] CORS_ORIGIN entry "${origin}" is unlikely to ever match: ` +
26
+ "origins are compared byte-for-byte against the browser's Origin " +
27
+ 'header, which is lowercase scheme://host[:port] with no trailing ' +
28
+ 'slash. Wildcard subdomains are not supported.');
29
+ }
30
+ }
31
+ return { origin: origins, ...corsBase };
32
+ }
33
+ function warnIfCorsDisabled(cors, warn = console.warn) {
34
+ if (cors !== false)
35
+ return;
36
+ warn('[cors] CORS_ORIGIN is unset — cross-origin browser requests are blocked ' +
37
+ '(same-origin only), and they will fail silently from this server\'s side. ' +
38
+ 'Set CORS_ORIGIN to your frontend origin(s), or to "*" for a public API ' +
39
+ 'any browser may call.');
40
+ }
41
+ //# sourceMappingURL=cors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cors.js","sourceRoot":"","sources":["../../../src/server/cors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,CAAC;AAGlD,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AAGrC,MAAM,YAAY,GAAG,CAAC,cAAc,CAAC,CAAC;AAkBtC,MAAM,QAAQ,GAAG;IACf,OAAO,EAAE,YAAY;IACrB,cAAc,EAAE,YAAY;IAC5B,WAAW,EAAE,KAAK;CACV,CAAC;AAeX,SAAS,kBAAkB,CACzB,MAA0C,OAAO,CAAC,GAAG;IAErD,MAAM,GAAG,GAAG,GAAG,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC;IACpC,IAAI,CAAC,GAAG;QAAE,OAAO,KAAK,CAAC;IACvB,IAAI,GAAG,KAAK,GAAG;QAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;IAErD,MAAM,OAAO,GAAG,GAAG;SAChB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;SAC9B,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAIzC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAEvC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IACE,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;YACpB,MAAM,KAAK,MAAM,CAAC,WAAW,EAAE;YAC/B,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EACpB,CAAC;YACD,OAAO,CAAC,IAAI,CACV,6BAA6B,MAAM,+BAA+B;gBAChE,kEAAkE;gBAClE,mEAAmE;gBACnE,+CAA+C,CAClD,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,EAAE,CAAC;AAC1C,CAAC;AAUD,SAAS,kBAAkB,CACzB,IAAgB,EAChB,OAAkC,OAAO,CAAC,IAAI;IAE9C,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO;IAC3B,IAAI,CACF,0EAA0E;QACxE,4EAA4E;QAC5E,yEAAyE;QACzE,uBAAuB,CAC1B,CAAC;AACJ,CAAC"}