@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.
- package/LICENSE +201 -0
- package/README.md +92 -268
- package/build/src/blockchain/utils.js.map +1 -1
- package/build/src/config.js +86 -0
- package/build/src/config.js.map +1 -0
- package/build/src/db/archive-node-adapter/archive-node-adapter.js +29 -2
- package/build/src/db/archive-node-adapter/archive-node-adapter.js.map +1 -1
- package/build/src/db/archive-node-adapter/postgres-options.js +35 -0
- package/build/src/db/archive-node-adapter/postgres-options.js.map +1 -0
- package/build/src/db/sql/best-chain.js +5 -0
- package/build/src/db/sql/best-chain.js.map +1 -0
- package/build/src/db/sql/events-actions/queries.js +102 -21
- package/build/src/db/sql/events-actions/queries.js.map +1 -1
- package/build/src/db/sql/verification-key-updates/queries.js +100 -0
- package/build/src/db/sql/verification-key-updates/queries.js.map +1 -0
- package/build/src/db/sql/zkapp-commands/queries.js +363 -0
- package/build/src/db/sql/zkapp-commands/queries.js.map +1 -0
- package/build/src/db/sql/zkapp-commands/types.js +2 -0
- package/build/src/db/sql/zkapp-commands/types.js.map +1 -0
- package/build/src/errors/error.js +4 -1
- package/build/src/errors/error.js.map +1 -1
- package/build/src/index.js +44 -7
- package/build/src/index.js.map +1 -1
- package/build/src/resolvers.js +42 -23
- package/build/src/resolvers.js.map +1 -1
- package/build/src/schema-version.js +2 -0
- package/build/src/schema-version.js.map +1 -0
- package/build/src/server/cors.js +41 -0
- package/build/src/server/cors.js.map +1 -0
- package/build/src/server/graceful-shutdown.js +42 -0
- package/build/src/server/graceful-shutdown.js.map +1 -0
- package/build/src/server/graphql-armor.js +39 -0
- package/build/src/server/graphql-armor.js.map +1 -0
- package/build/src/server/logger.js +45 -0
- package/build/src/server/logger.js.map +1 -0
- package/build/src/server/metrics.js +72 -0
- package/build/src/server/metrics.js.map +1 -0
- package/build/src/server/plugins.js +31 -15
- package/build/src/server/plugins.js.map +1 -1
- package/build/src/server/rate-limit.js +143 -0
- package/build/src/server/rate-limit.js.map +1 -0
- package/build/src/server/readiness.js +45 -0
- package/build/src/server/readiness.js.map +1 -0
- package/build/src/server/request-logging.js +58 -0
- package/build/src/server/request-logging.js.map +1 -0
- package/build/src/server/server.js +38 -13
- package/build/src/server/server.js.map +1 -1
- package/build/src/services/actions-service/actions-service.js +26 -15
- package/build/src/services/actions-service/actions-service.js.map +1 -1
- package/build/src/services/blocks-service/blocks-service.js +10 -9
- package/build/src/services/blocks-service/blocks-service.js.map +1 -1
- package/build/src/services/network-service/network-service.js +17 -9
- package/build/src/services/network-service/network-service.js.map +1 -1
- package/build/src/services/verification-key-updates-service/verification-key-updates-service.interface.js +2 -0
- package/build/src/services/verification-key-updates-service/verification-key-updates-service.interface.js.map +1 -0
- package/build/src/services/verification-key-updates-service/verification-key-updates-service.js +41 -0
- package/build/src/services/verification-key-updates-service/verification-key-updates-service.js.map +1 -0
- package/build/src/services/zkapp-commands-service/zkapp-commands-service.interface.js +2 -0
- package/build/src/services/zkapp-commands-service/zkapp-commands-service.interface.js.map +1 -0
- package/build/src/services/zkapp-commands-service/zkapp-commands-service.js +115 -0
- package/build/src/services/zkapp-commands-service/zkapp-commands-service.js.map +1 -0
- package/build/src/tracing/jaeger-tracing.js +2 -1
- package/build/src/tracing/jaeger-tracing.js.map +1 -1
- package/build/tests/devnet-dump/action-state-invariants.js +165 -0
- package/build/tests/devnet-dump/action-state-invariants.js.map +1 -0
- package/build/tests/devnet-dump/devnet-dump.test.js +24 -10
- package/build/tests/devnet-dump/devnet-dump.test.js.map +1 -1
- package/build/tests/devnet-dump/setup.js +63 -17
- package/build/tests/devnet-dump/setup.js.map +1 -1
- package/build/tests/integration/action-state-ordering.test.js +139 -0
- package/build/tests/integration/action-state-ordering.test.js.map +1 -0
- package/build/tests/integration/action-state-setup.js +48 -0
- package/build/tests/integration/action-state-setup.js.map +1 -0
- package/build/tests/integration/consensus-vs-chain.test.js +81 -0
- package/build/tests/integration/consensus-vs-chain.test.js.map +1 -0
- package/build/tests/integration/integration.test.js +166 -2
- package/build/tests/integration/integration.test.js.map +1 -1
- package/build/tests/integration/postgres-timeout.test.js +92 -0
- package/build/tests/integration/postgres-timeout.test.js.map +1 -0
- package/build/tests/integration/setup.js +58 -1
- package/build/tests/integration/setup.js.map +1 -1
- package/build/tests/integration/verification-key-setup.js +49 -0
- package/build/tests/integration/verification-key-setup.js.map +1 -0
- package/build/tests/integration/verification-key-updates.test.js +159 -0
- package/build/tests/integration/verification-key-updates.test.js.map +1 -0
- package/build/tests/live-api/events.test.js +11 -7
- package/build/tests/live-api/events.test.js.map +1 -1
- package/build/tests/live-api/networkState.test.js +1 -0
- package/build/tests/live-api/networkState.test.js.map +1 -1
- package/build/tests/live-network/live-network.test.js +1 -0
- package/build/tests/live-network/live-network.test.js.map +1 -1
- package/build/tests/resolvers.test.js +65 -37
- package/build/tests/resolvers.test.js.map +1 -1
- package/build/tests/services/verification-key-updates-service/verification-key-updates-service.test.js +35 -0
- package/build/tests/services/verification-key-updates-service/verification-key-updates-service.test.js.map +1 -0
- package/build/tests/services/zkapp-commands-service/zkapp-commands-service.test.js +159 -0
- package/build/tests/services/zkapp-commands-service/zkapp-commands-service.test.js.map +1 -0
- package/build/tests/test-helpers.js +15 -0
- package/build/tests/test-helpers.js.map +1 -1
- package/build/tests/unit/best-chain-anchor.test.js +70 -0
- package/build/tests/unit/best-chain-anchor.test.js.map +1 -0
- package/build/tests/unit/config.test.js +106 -0
- package/build/tests/unit/config.test.js.map +1 -0
- package/build/tests/unit/cors.test.js +95 -0
- package/build/tests/unit/cors.test.js.map +1 -0
- package/build/tests/unit/error-masking.test.js +119 -0
- package/build/tests/unit/error-masking.test.js.map +1 -0
- package/build/tests/unit/graceful-shutdown.test.js +99 -0
- package/build/tests/unit/graceful-shutdown.test.js.map +1 -0
- package/build/tests/unit/graphql-armor.test.js +121 -0
- package/build/tests/unit/graphql-armor.test.js.map +1 -0
- package/build/tests/unit/logging.test.js +120 -0
- package/build/tests/unit/logging.test.js.map +1 -0
- package/build/tests/unit/metrics.test.js +114 -0
- package/build/tests/unit/metrics.test.js.map +1 -0
- package/build/tests/unit/network-service.test.js +66 -0
- package/build/tests/unit/network-service.test.js.map +1 -0
- package/build/tests/unit/postgres-options.test.js +56 -0
- package/build/tests/unit/postgres-options.test.js.map +1 -0
- package/build/tests/unit/rate-limit.test.js +271 -0
- package/build/tests/unit/rate-limit.test.js.map +1 -0
- package/build/tests/unit/readiness.test.js +75 -0
- package/build/tests/unit/readiness.test.js.map +1 -0
- package/build/tests/unit/schema-nullability.test.js +40 -0
- package/build/tests/unit/schema-nullability.test.js.map +1 -0
- package/build/tests/unit/schema-version.test.js +48 -0
- package/build/tests/unit/schema-version.test.js.map +1 -0
- package/build/tests/unit/yoga-http-contract.test.js +30 -0
- package/build/tests/unit/yoga-http-contract.test.js.map +1 -0
- package/build/tests/unit/zkapp-commands-gating.test.js +38 -0
- package/build/tests/unit/zkapp-commands-gating.test.js.map +1 -0
- package/build/zkapp/utils.js +2 -0
- package/build/zkapp/utils.js.map +1 -1
- package/package.json +33 -14
- package/schema.graphql +126 -8
- package/src/blockchain/types.ts +65 -1
- package/src/blockchain/utils.ts +26 -2
- package/src/config.ts +133 -0
- package/src/db/archive-node-adapter/archive-node-adapter.interface.ts +26 -3
- package/src/db/archive-node-adapter/archive-node-adapter.ts +65 -2
- package/src/db/archive-node-adapter/postgres-options.ts +90 -0
- package/src/db/sql/best-chain.ts +34 -0
- package/src/db/sql/events-actions/queries.ts +168 -24
- package/src/db/sql/verification-key-updates/queries.ts +132 -0
- package/src/db/sql/zkapp-commands/queries.ts +406 -0
- package/src/db/sql/zkapp-commands/types.ts +43 -0
- package/src/envionment.d.ts +20 -0
- package/src/errors/error.ts +17 -1
- package/src/index.ts +64 -7
- package/src/resolvers-types.ts +311 -24
- package/src/resolvers.ts +70 -34
- package/src/schema-version.ts +24 -0
- package/src/server/cors.ts +97 -0
- package/src/server/graceful-shutdown.ts +76 -0
- package/src/server/graphql-armor.ts +78 -0
- package/src/server/logger.ts +72 -0
- package/src/server/metrics.ts +104 -0
- package/src/server/plugins.ts +53 -19
- package/src/server/rate-limit.ts +274 -0
- package/src/server/readiness.ts +78 -0
- package/src/server/request-logging.ts +83 -0
- package/src/server/server.ts +70 -15
- package/src/services/actions-service/actions-service.ts +87 -24
- package/src/services/blocks-service/blocks-service.ts +16 -14
- package/src/services/network-service/network-service.ts +30 -12
- package/src/services/verification-key-updates-service/verification-key-updates-service.interface.ts +9 -0
- package/src/services/verification-key-updates-service/verification-key-updates-service.ts +72 -0
- package/src/services/zkapp-commands-service/zkapp-commands-service.interface.ts +9 -0
- package/src/services/zkapp-commands-service/zkapp-commands-service.ts +181 -0
- package/src/tracing/jaeger-tracing.ts +2 -1
- package/build/tests/consensus/run-compare.js +0 -40
- package/build/tests/consensus/run-compare.js.map +0 -1
- package/build/tests/consensus/select-consensus-precomputed.js +0 -80
- package/build/tests/consensus/select-consensus-precomputed.js.map +0 -1
- package/build/tests/consensus/types.js +0 -15
- package/build/tests/consensus/types.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@o1-labs/mina-archive-node-graphql",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "A NodeJS GraphQL server for exposing Mina Protocol archive node data for o1js/zkApps",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -24,9 +24,10 @@
|
|
|
24
24
|
"start": "node build/src/index.js",
|
|
25
25
|
"dev": "cross-env NODE_NO_WARNINGS=1 npx nodemon --exec 'node -r dotenv/config --loader ts-node/esm' src/index.ts",
|
|
26
26
|
"test": "./run-tests.sh",
|
|
27
|
-
"test:unit": "npm run build && for f in ./build/tests/unit/*test.js ./build/tests/utils.test.js ./build/tests/services/*/*.test.js; do node --enable-source-maps --test \"$f\";
|
|
28
|
-
"test:coverage": "npm run build && npx c8 --include 'build/src/**' --reporter text --reporter lcov -- bash -c 'for f in ./build/tests/unit/*test.js ./build/tests/utils.test.js ./build/tests/services/*/*.test.js; do node --enable-source-maps --test \"$f\";
|
|
29
|
-
"test:integration": "npm run build && node --enable-source-maps --test
|
|
27
|
+
"test:unit": "npm run build && (ec=0; for f in ./build/tests/unit/*test.js ./build/tests/utils.test.js ./build/tests/services/*/*.test.js; do node --enable-source-maps --test \"$f\" || ec=$?; done; exit $ec)",
|
|
28
|
+
"test:coverage": "npm run build && npx c8 --include 'build/src/**' --check-coverage --lines 50 --functions 50 --statements 50 --branches 80 --reporter text --reporter lcov -- bash -c 'ec=0; for f in ./build/tests/unit/*test.js ./build/tests/utils.test.js ./build/tests/services/*/*.test.js; do node --enable-source-maps --test \"$f\" || ec=$?; done; exit $ec'",
|
|
29
|
+
"test:integration": "npm run build && (ec=0; for f in ./build/tests/integration/*.test.js; do node --enable-source-maps --test \"$f\" || ec=$?; done; exit $ec)",
|
|
30
|
+
"test:live-api": "npm run build && node --enable-source-maps --test ./build/tests/live-api/*.test.js",
|
|
30
31
|
"test:live-network": "npm run build && node --enable-source-maps --test-timeout 600000 --test ./build/tests/live-network/live-network.test.js",
|
|
31
32
|
"test:devnet-dump": "npm run build && node --enable-source-maps --test-timeout 900000 --test ./build/tests/devnet-dump/devnet-dump.test.js",
|
|
32
33
|
"clean": "rimraf ./build",
|
|
@@ -38,15 +39,26 @@
|
|
|
38
39
|
"compose": "docker compose up",
|
|
39
40
|
"prepublishOnly": "npm run build"
|
|
40
41
|
},
|
|
41
|
-
"keywords": [
|
|
42
|
+
"keywords": [
|
|
43
|
+
"mina",
|
|
44
|
+
"mina-protocol",
|
|
45
|
+
"archive-node",
|
|
46
|
+
"graphql",
|
|
47
|
+
"o1js",
|
|
48
|
+
"zkapp",
|
|
49
|
+
"blockchain"
|
|
50
|
+
],
|
|
42
51
|
"author": "O(1) Labs <build@o1labs.org>",
|
|
43
|
-
"license": "
|
|
52
|
+
"license": "Apache-2.0",
|
|
53
|
+
"engines": {
|
|
54
|
+
"node": ">=22.12.0"
|
|
55
|
+
},
|
|
44
56
|
"devDependencies": {
|
|
45
57
|
"@graphql-codegen/cli": "^6.0.1",
|
|
46
58
|
"@graphql-codegen/typescript": "^5.0.2",
|
|
47
59
|
"@graphql-codegen/typescript-resolvers": "^5.0.1",
|
|
48
60
|
"@graphql-eslint/eslint-plugin": "^4.4.0",
|
|
49
|
-
"@types/node": "^20.
|
|
61
|
+
"@types/node": "^22.20.1",
|
|
50
62
|
"@typescript-eslint/eslint-plugin": "^6.5.0",
|
|
51
63
|
"@typescript-eslint/parser": "^6.5.0",
|
|
52
64
|
"artillery": "^2.0.0-36",
|
|
@@ -62,10 +74,15 @@
|
|
|
62
74
|
"typescript": "^5.2.2"
|
|
63
75
|
},
|
|
64
76
|
"dependencies": {
|
|
65
|
-
"@envelop/core": "^
|
|
66
|
-
"@envelop/disable-introspection": "^
|
|
67
|
-
"@envelop/graphql-jit": "^
|
|
68
|
-
"@envelop/opentelemetry": "^
|
|
77
|
+
"@envelop/core": "^5.5.1",
|
|
78
|
+
"@envelop/disable-introspection": "^9.1.1",
|
|
79
|
+
"@envelop/graphql-jit": "^11.1.1",
|
|
80
|
+
"@envelop/opentelemetry": "^9.1.1",
|
|
81
|
+
"@escape.tech/graphql-armor-block-field-suggestions": "^3.0.1",
|
|
82
|
+
"@escape.tech/graphql-armor-cost-limit": "^2.4.3",
|
|
83
|
+
"@escape.tech/graphql-armor-max-aliases": "^2.6.2",
|
|
84
|
+
"@escape.tech/graphql-armor-max-depth": "^2.4.2",
|
|
85
|
+
"@escape.tech/graphql-armor-max-tokens": "^2.5.1",
|
|
69
86
|
"@graphql-tools/executor-http": "^3.0.4",
|
|
70
87
|
"@graphql-tools/graphql-file-loader": "^8.1.2",
|
|
71
88
|
"@graphql-tools/load": "^8.1.2",
|
|
@@ -76,10 +93,12 @@
|
|
|
76
93
|
"blakejs": "^1.2.1",
|
|
77
94
|
"dotenv": "^16.3.1",
|
|
78
95
|
"graphql": "^16.8.0",
|
|
79
|
-
"graphql-yoga": "
|
|
80
|
-
"
|
|
96
|
+
"graphql-yoga": "5.21.2",
|
|
97
|
+
"pino": "^10.3.1",
|
|
98
|
+
"postgres": "^3.3.5",
|
|
99
|
+
"prom-client": "^15.1.3"
|
|
81
100
|
},
|
|
82
101
|
"volta": {
|
|
83
|
-
"node": "
|
|
102
|
+
"node": "22.12.0"
|
|
84
103
|
}
|
|
85
104
|
}
|
package/schema.graphql
CHANGED
|
@@ -66,16 +66,54 @@ input ActionFilterOptionsInput {
|
|
|
66
66
|
endActionState: String
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
"""
|
|
70
|
+
Find applied account updates that set a specific verification key.
|
|
71
|
+
|
|
72
|
+
The block range is required and limited by the server's configured maximum.
|
|
73
|
+
`from` is inclusive and `to` is exclusive.
|
|
74
|
+
"""
|
|
75
|
+
input VerificationKeyUpdateFilterInput {
|
|
76
|
+
verificationKeyHash: String!
|
|
77
|
+
from: Int!
|
|
78
|
+
to: Int!
|
|
79
|
+
status: BlockStatusFilter
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
"""
|
|
83
|
+
Filter successful zkApp commands by block range.
|
|
84
|
+
|
|
85
|
+
Both `from` and `to` are required. The range is bounded by `ZKAPP_COMMAND_RANGE_SIZE`, and the server may reject dense ranges that expand to too many account updates.
|
|
86
|
+
"""
|
|
87
|
+
input ZkappCommandFilterOptionsInput {
|
|
88
|
+
blockStatus: BlockStatusFilter
|
|
89
|
+
"""
|
|
90
|
+
Mina block height to filter zkApp commands from, inclusive
|
|
91
|
+
"""
|
|
92
|
+
from: Int!
|
|
93
|
+
"""
|
|
94
|
+
Mina block height to filter zkApp commands to, exclusive
|
|
95
|
+
"""
|
|
96
|
+
to: Int!
|
|
97
|
+
"""
|
|
98
|
+
Optional account update public key filter.
|
|
99
|
+
"""
|
|
100
|
+
accountPublicKey: String
|
|
101
|
+
"""
|
|
102
|
+
Optional account update token id filter.
|
|
103
|
+
"""
|
|
104
|
+
tokenId: String
|
|
105
|
+
}
|
|
106
|
+
|
|
69
107
|
type EventData {
|
|
70
108
|
accountUpdateId: String!
|
|
71
109
|
transactionInfo: TransactionInfo
|
|
72
|
-
data: [String]!
|
|
110
|
+
data: [String!]!
|
|
73
111
|
}
|
|
74
112
|
|
|
75
113
|
type ActionData {
|
|
76
114
|
accountUpdateId: String!
|
|
77
115
|
transactionInfo: TransactionInfo
|
|
78
|
-
data: [String]!
|
|
116
|
+
data: [String!]!
|
|
79
117
|
}
|
|
80
118
|
|
|
81
119
|
type BlockInfo {
|
|
@@ -101,7 +139,16 @@ type TransactionInfo {
|
|
|
101
139
|
memo: String!
|
|
102
140
|
authorizationKind: String!
|
|
103
141
|
sequenceNumber: Int!
|
|
104
|
-
zkappAccountUpdateIds: [Int]!
|
|
142
|
+
zkappAccountUpdateIds: [Int!]!
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
type VerificationKeyUpdate {
|
|
146
|
+
accountUpdateId: String!
|
|
147
|
+
address: String!
|
|
148
|
+
tokenId: String!
|
|
149
|
+
verificationKeyHash: String!
|
|
150
|
+
blockInfo: BlockInfo!
|
|
151
|
+
transactionInfo: TransactionInfo!
|
|
105
152
|
}
|
|
106
153
|
|
|
107
154
|
type ActionStates {
|
|
@@ -114,16 +161,67 @@ type ActionStates {
|
|
|
114
161
|
|
|
115
162
|
type EventOutput {
|
|
116
163
|
blockInfo: BlockInfo
|
|
117
|
-
eventData: [EventData]
|
|
164
|
+
eventData: [EventData!]
|
|
118
165
|
}
|
|
119
166
|
|
|
120
167
|
type ActionOutput {
|
|
121
168
|
blockInfo: BlockInfo
|
|
122
169
|
transactionInfo: TransactionInfo
|
|
123
|
-
actionData: [ActionData]
|
|
170
|
+
actionData: [ActionData!]
|
|
124
171
|
actionState: ActionStates!
|
|
125
172
|
}
|
|
126
173
|
|
|
174
|
+
"""
|
|
175
|
+
Raw field array from the archive database.
|
|
176
|
+
|
|
177
|
+
An empty `fields` array means the archive row exists but contains no field values.
|
|
178
|
+
Nullable entries mean the corresponding nullable archive state slot has no field value.
|
|
179
|
+
"""
|
|
180
|
+
type ZkappFieldArray {
|
|
181
|
+
fields: [String]!
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
type ZkappAccountPrecondition {
|
|
185
|
+
state: ZkappFieldArray
|
|
186
|
+
actionState: ZkappFieldArray
|
|
187
|
+
provedState: Boolean
|
|
188
|
+
isNew: Boolean
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
type ZkappGlobalSlotBounds {
|
|
192
|
+
lowerBound: Int
|
|
193
|
+
upperBound: Int
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
type ZkappNetworkPrecondition {
|
|
197
|
+
globalSlotSinceGenesis: ZkappGlobalSlotBounds
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
type ZkappAccountUpdateOutput {
|
|
201
|
+
id: String!
|
|
202
|
+
publicKey: String!
|
|
203
|
+
tokenId: String!
|
|
204
|
+
authorizationKind: String!
|
|
205
|
+
balanceChange: String!
|
|
206
|
+
incrementNonce: Boolean!
|
|
207
|
+
callDepth: Int!
|
|
208
|
+
actions: [ZkappFieldArray!]!
|
|
209
|
+
events: [ZkappFieldArray!]!
|
|
210
|
+
appState: ZkappFieldArray
|
|
211
|
+
accountPrecondition: ZkappAccountPrecondition
|
|
212
|
+
networkPrecondition: ZkappNetworkPrecondition
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
type ZkappCommandOutput {
|
|
216
|
+
blockInfo: BlockInfo!
|
|
217
|
+
hash: String!
|
|
218
|
+
feePayer: String!
|
|
219
|
+
fee: String!
|
|
220
|
+
memo: String!
|
|
221
|
+
sequenceNumber: Int!
|
|
222
|
+
accountUpdates: [ZkappAccountUpdateOutput!]!
|
|
223
|
+
}
|
|
224
|
+
|
|
127
225
|
"""
|
|
128
226
|
Metadata about the network
|
|
129
227
|
"""
|
|
@@ -214,8 +312,28 @@ type Block {
|
|
|
214
312
|
}
|
|
215
313
|
|
|
216
314
|
type Query {
|
|
217
|
-
|
|
218
|
-
|
|
315
|
+
"""
|
|
316
|
+
The `MAJOR.MINOR` version of this schema.
|
|
317
|
+
|
|
318
|
+
Clients compare it with the schema version they were built against: an equal
|
|
319
|
+
major means the contract they code against still holds, and a higher minor
|
|
320
|
+
means this server has additive changes they may not know about yet.
|
|
321
|
+
|
|
322
|
+
Always available, even when `ENABLED_QUERIES` restricts which data queries
|
|
323
|
+
this server exposes — a compatibility check that can itself be switched off
|
|
324
|
+
is of no use to a client.
|
|
325
|
+
"""
|
|
326
|
+
schemaVersion: String!
|
|
327
|
+
events(input: EventFilterOptionsInput!): [EventOutput!]!
|
|
328
|
+
actions(input: ActionFilterOptionsInput!): [ActionOutput!]!
|
|
329
|
+
verificationKeyUpdates(
|
|
330
|
+
input: VerificationKeyUpdateFilterInput!
|
|
331
|
+
): [VerificationKeyUpdate!]!
|
|
332
|
+
zkappCommands(input: ZkappCommandFilterOptionsInput!): [ZkappCommandOutput!]!
|
|
219
333
|
networkState: NetworkStateOutput!
|
|
220
|
-
blocks(
|
|
334
|
+
blocks(
|
|
335
|
+
query: BlockQueryInput
|
|
336
|
+
limit: Int
|
|
337
|
+
sortBy: BlockSortByInput
|
|
338
|
+
): [Block!]!
|
|
221
339
|
}
|
package/src/blockchain/types.ts
CHANGED
|
@@ -25,7 +25,9 @@ export type Action = {
|
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
export type NetworkState = {
|
|
28
|
-
|
|
28
|
+
// Nullable when the archive has no canonical or pending blocks indexed yet.
|
|
29
|
+
// Matches the schema: NetworkStateOutput.maxBlockHeight is nullable.
|
|
30
|
+
maxBlockHeight: MaxBlockHeightInfo | null;
|
|
29
31
|
};
|
|
30
32
|
|
|
31
33
|
export type MaxBlockHeightInfo = {
|
|
@@ -55,6 +57,17 @@ export type TransactionInfo = {
|
|
|
55
57
|
zkappAccountUpdateIds: number[];
|
|
56
58
|
};
|
|
57
59
|
|
|
60
|
+
export type VerificationKeyUpdate = {
|
|
61
|
+
accountUpdateId: string;
|
|
62
|
+
address: string;
|
|
63
|
+
tokenId: string;
|
|
64
|
+
verificationKeyHash: string;
|
|
65
|
+
blockInfo: BlockInfo;
|
|
66
|
+
transactionInfo: TransactionInfo;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export type VerificationKeyUpdates = VerificationKeyUpdate[];
|
|
70
|
+
|
|
58
71
|
export type Events = {
|
|
59
72
|
eventData: Event[];
|
|
60
73
|
blockInfo: BlockInfo;
|
|
@@ -96,6 +109,57 @@ export type ZkAppCommand = {
|
|
|
96
109
|
failureReason: string | null;
|
|
97
110
|
};
|
|
98
111
|
|
|
112
|
+
export type ZkappAccountPrecondition = {
|
|
113
|
+
state: ZkappFieldArray | null;
|
|
114
|
+
actionState: ZkappFieldArray | null;
|
|
115
|
+
provedState: boolean | null;
|
|
116
|
+
isNew: boolean | null;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export type ZkappFieldArray = {
|
|
120
|
+
fields: (string | null)[];
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export type ZkappNestedFieldArray = {
|
|
124
|
+
fields: string[];
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
export type ZkappGlobalSlotBounds = {
|
|
128
|
+
lowerBound: number | null;
|
|
129
|
+
upperBound: number | null;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export type ZkappNetworkPrecondition = {
|
|
133
|
+
globalSlotSinceGenesis: ZkappGlobalSlotBounds;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
export type ZkappAccountUpdate = {
|
|
137
|
+
id: string;
|
|
138
|
+
publicKey: string;
|
|
139
|
+
tokenId: string;
|
|
140
|
+
authorizationKind: string;
|
|
141
|
+
balanceChange: string;
|
|
142
|
+
incrementNonce: boolean;
|
|
143
|
+
callDepth: number;
|
|
144
|
+
actions: ZkappNestedFieldArray[];
|
|
145
|
+
events: ZkappNestedFieldArray[];
|
|
146
|
+
appState: ZkappFieldArray | null;
|
|
147
|
+
accountPrecondition: ZkappAccountPrecondition;
|
|
148
|
+
networkPrecondition: ZkappNetworkPrecondition;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export type ZkappCommand = {
|
|
152
|
+
blockInfo: BlockInfo;
|
|
153
|
+
hash: string;
|
|
154
|
+
feePayer: string;
|
|
155
|
+
fee: string;
|
|
156
|
+
memo: string;
|
|
157
|
+
sequenceNumber: number;
|
|
158
|
+
accountUpdates: ZkappAccountUpdate[];
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
export type ZkappCommands = ZkappCommand[];
|
|
162
|
+
|
|
99
163
|
export type FeeTransfer = {
|
|
100
164
|
recipient: string;
|
|
101
165
|
fee: string;
|
package/src/blockchain/utils.ts
CHANGED
|
@@ -1,7 +1,31 @@
|
|
|
1
1
|
import type { BlockInfo, TransactionInfo, Event, Action } from './types.js';
|
|
2
2
|
import type { ArchiveNodeDatabaseRow } from '../db/sql/events-actions/types.js';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
type BlockInfoRow = Pick<
|
|
5
|
+
ArchiveNodeDatabaseRow,
|
|
6
|
+
| 'height'
|
|
7
|
+
| 'state_hash'
|
|
8
|
+
| 'parent_hash'
|
|
9
|
+
| 'ledger_hash'
|
|
10
|
+
| 'chain_status'
|
|
11
|
+
| 'timestamp'
|
|
12
|
+
| 'global_slot_since_hard_fork'
|
|
13
|
+
| 'global_slot_since_genesis'
|
|
14
|
+
| 'distance_from_max_block_height'
|
|
15
|
+
| 'last_vrf_output'
|
|
16
|
+
>;
|
|
17
|
+
|
|
18
|
+
type TransactionInfoRow = Pick<
|
|
19
|
+
ArchiveNodeDatabaseRow,
|
|
20
|
+
| 'status'
|
|
21
|
+
| 'hash'
|
|
22
|
+
| 'memo'
|
|
23
|
+
| 'authorization_kind'
|
|
24
|
+
| 'sequence_number'
|
|
25
|
+
| 'zkapp_account_updates_ids'
|
|
26
|
+
>;
|
|
27
|
+
|
|
28
|
+
export function createBlockInfo(row: BlockInfoRow): BlockInfo {
|
|
5
29
|
return {
|
|
6
30
|
height: Number(row.height),
|
|
7
31
|
stateHash: row.state_hash,
|
|
@@ -17,7 +41,7 @@ export function createBlockInfo(row: ArchiveNodeDatabaseRow): BlockInfo {
|
|
|
17
41
|
}
|
|
18
42
|
|
|
19
43
|
export function createTransactionInfo(
|
|
20
|
-
row:
|
|
44
|
+
row: TransactionInfoRow
|
|
21
45
|
): TransactionInfo {
|
|
22
46
|
return {
|
|
23
47
|
status: row.status,
|
package/src/config.ts
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
export { parseBoolean, validateConfig, assertValidConfig };
|
|
2
|
+
|
|
3
|
+
type EnvSource = Record<string, string | undefined>;
|
|
4
|
+
|
|
5
|
+
const TRUE_VALUES = new Set(['true', '1', 'yes', 'on']);
|
|
6
|
+
const FALSE_VALUES = new Set(['false', '0', 'no', 'off']);
|
|
7
|
+
|
|
8
|
+
/** Env vars interpreted as booleans. */
|
|
9
|
+
const BOOLEAN_VARS = [
|
|
10
|
+
'ENABLE_GRAPHIQL',
|
|
11
|
+
'ENABLE_INTROSPECTION',
|
|
12
|
+
'ENABLE_LOGGING',
|
|
13
|
+
'ENABLE_METRICS',
|
|
14
|
+
'ENABLE_JAEGER',
|
|
15
|
+
'ENABLE_BLOCK_TRANSACTION_DETAILS',
|
|
16
|
+
'ENABLE_ZKAPP_COMMANDS_QUERY',
|
|
17
|
+
] as const;
|
|
18
|
+
|
|
19
|
+
/** Env vars that, when set, must be positive integers. */
|
|
20
|
+
const POSITIVE_INT_VARS = ['PORT', 'BLOCK_RANGE_SIZE'] as const;
|
|
21
|
+
|
|
22
|
+
/** Root query fields in schema.graphql — keep in sync. */
|
|
23
|
+
const KNOWN_QUERIES = [
|
|
24
|
+
'events',
|
|
25
|
+
'actions',
|
|
26
|
+
'verificationKeyUpdates',
|
|
27
|
+
'zkappCommands',
|
|
28
|
+
'networkState',
|
|
29
|
+
'blocks',
|
|
30
|
+
] as const;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Parse a boolean environment value. Recognises `true/false`, `1/0`, `yes/no`,
|
|
34
|
+
* `on/off` (case-insensitive). Anything unrecognised — including the empty
|
|
35
|
+
* string or `undefined` — yields `fallback`.
|
|
36
|
+
*
|
|
37
|
+
* This replaces ad-hoc truthiness checks like `if (process.env.ENABLE_X)`, which
|
|
38
|
+
* treated the string `"false"` as `true` (#74).
|
|
39
|
+
*/
|
|
40
|
+
function parseBoolean(value: string | undefined, fallback = false): boolean {
|
|
41
|
+
if (value === undefined) return fallback;
|
|
42
|
+
const normalized = value.trim().toLowerCase();
|
|
43
|
+
if (normalized === '') return fallback;
|
|
44
|
+
if (TRUE_VALUES.has(normalized)) return true;
|
|
45
|
+
if (FALSE_VALUES.has(normalized)) return false;
|
|
46
|
+
return fallback;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function isRecognisedBoolean(value: string): boolean {
|
|
50
|
+
const normalized = value.trim().toLowerCase();
|
|
51
|
+
return TRUE_VALUES.has(normalized) || FALSE_VALUES.has(normalized);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Validate the environment, returning a list of human-readable problems (empty
|
|
56
|
+
* when valid). Catches the common misconfigurations — a missing connection
|
|
57
|
+
* string, a non-numeric port, a mistyped boolean — so they surface at startup
|
|
58
|
+
* rather than as confusing runtime behaviour.
|
|
59
|
+
*/
|
|
60
|
+
function validateConfig(env: EnvSource = process.env): string[] {
|
|
61
|
+
const errors: string[] = [];
|
|
62
|
+
|
|
63
|
+
if (!env.PG_CONN || env.PG_CONN.trim() === '') {
|
|
64
|
+
errors.push('PG_CONN is required (Postgres connection string).');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
for (const name of BOOLEAN_VARS) {
|
|
68
|
+
const value = env[name];
|
|
69
|
+
if (
|
|
70
|
+
value !== undefined &&
|
|
71
|
+
value.trim() !== '' &&
|
|
72
|
+
!isRecognisedBoolean(value)
|
|
73
|
+
) {
|
|
74
|
+
errors.push(`${name} must be a boolean (true/false), got "${value}".`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
for (const name of POSITIVE_INT_VARS) {
|
|
79
|
+
const value = env[name];
|
|
80
|
+
if (value !== undefined && value.trim() !== '') {
|
|
81
|
+
const parsed = Number(value);
|
|
82
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
83
|
+
errors.push(`${name} must be a positive integer, got "${value}".`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const enabledQueries = env.ENABLED_QUERIES;
|
|
89
|
+
if (enabledQueries !== undefined) {
|
|
90
|
+
const names = enabledQueries
|
|
91
|
+
.split(',')
|
|
92
|
+
.map((query) => query.trim())
|
|
93
|
+
.filter((query) => query !== '');
|
|
94
|
+
if (names.length === 0) {
|
|
95
|
+
errors.push(
|
|
96
|
+
'ENABLED_QUERIES is set but lists no queries; unset it to expose all of ' +
|
|
97
|
+
`${KNOWN_QUERIES.join(', ')}.`
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// schemaVersion is served whatever this lists (see src/resolvers.ts), so
|
|
102
|
+
// naming it is redundant rather than wrong. Rejecting it would fail startup
|
|
103
|
+
// over a list that asks for exactly what it already gets.
|
|
104
|
+
const unknown = names.filter(
|
|
105
|
+
(name) =>
|
|
106
|
+
!(KNOWN_QUERIES as readonly string[]).includes(name) &&
|
|
107
|
+
name !== 'schemaVersion'
|
|
108
|
+
);
|
|
109
|
+
if (unknown.length > 0) {
|
|
110
|
+
errors.push(
|
|
111
|
+
`ENABLED_QUERIES contains unknown queries: ${unknown.join(', ')}. ` +
|
|
112
|
+
`Known queries: ${KNOWN_QUERIES.join(', ')}. ` +
|
|
113
|
+
'schemaVersion is always served and does not need listing.'
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return errors;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Validate the environment and throw a single aggregated error if anything is
|
|
123
|
+
* wrong, so the process fails fast at startup with a clear message instead of
|
|
124
|
+
* booting into a broken state.
|
|
125
|
+
*/
|
|
126
|
+
function assertValidConfig(env: EnvSource = process.env): void {
|
|
127
|
+
const errors = validateConfig(env);
|
|
128
|
+
if (errors.length > 0) {
|
|
129
|
+
throw new Error(
|
|
130
|
+
`Invalid configuration:\n${errors.map((e) => ` - ${e}`).join('\n')}`
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -1,23 +1,46 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
ActionFilterOptionsInput,
|
|
3
|
+
EventFilterOptionsInput,
|
|
4
|
+
VerificationKeyUpdateFilterInput,
|
|
5
|
+
ZkappCommandFilterOptionsInput,
|
|
6
|
+
} from '../../resolvers-types.js';
|
|
2
7
|
import type {
|
|
3
8
|
Actions,
|
|
4
9
|
Events,
|
|
5
10
|
NetworkState,
|
|
6
11
|
Blocks,
|
|
12
|
+
VerificationKeyUpdates,
|
|
13
|
+
ZkappCommands,
|
|
7
14
|
} from '../../blockchain/types.js';
|
|
8
|
-
import type {
|
|
15
|
+
import type {
|
|
16
|
+
BlockQueryInput,
|
|
17
|
+
BlockSortByInput,
|
|
18
|
+
} from '../../resolvers-types.js';
|
|
9
19
|
|
|
10
20
|
export interface DatabaseAdapter {
|
|
11
21
|
getEvents(input: EventFilterOptionsInput, options?: unknown): Promise<Events>;
|
|
12
22
|
getActions(
|
|
13
|
-
input:
|
|
23
|
+
input: ActionFilterOptionsInput,
|
|
14
24
|
options?: unknown
|
|
15
25
|
): Promise<Actions>;
|
|
26
|
+
getZkappCommands(
|
|
27
|
+
input: ZkappCommandFilterOptionsInput,
|
|
28
|
+
options?: unknown
|
|
29
|
+
): Promise<ZkappCommands>;
|
|
16
30
|
getNetworkState(options?: unknown): Promise<NetworkState>;
|
|
31
|
+
getVerificationKeyUpdates(
|
|
32
|
+
input: VerificationKeyUpdateFilterInput,
|
|
33
|
+
options?: unknown
|
|
34
|
+
): Promise<VerificationKeyUpdates>;
|
|
17
35
|
getBlocks(
|
|
18
36
|
query: BlockQueryInput | null | undefined,
|
|
19
37
|
limit: number | null | undefined,
|
|
20
38
|
sortBy: BlockSortByInput | null | undefined,
|
|
21
39
|
options: unknown
|
|
22
40
|
): Promise<Blocks>;
|
|
41
|
+
/**
|
|
42
|
+
* Lightweight connectivity check for readiness probes. Resolves `true` when the
|
|
43
|
+
* database answers a trivial query, `false` otherwise. Never throws.
|
|
44
|
+
*/
|
|
45
|
+
ping(): Promise<boolean>;
|
|
23
46
|
}
|