@aztec-labs/aztec-node 6.0.0-nightly.20260829

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 (83) hide show
  1. package/README.md +15 -0
  2. package/dest/aztec-node/block_response_helpers.d.ts +25 -0
  3. package/dest/aztec-node/block_response_helpers.d.ts.map +1 -0
  4. package/dest/aztec-node/block_response_helpers.js +112 -0
  5. package/dest/aztec-node/config.d.ts +52 -0
  6. package/dest/aztec-node/config.d.ts.map +1 -0
  7. package/dest/aztec-node/config.js +129 -0
  8. package/dest/aztec-node/node_metrics.d.ts +12 -0
  9. package/dest/aztec-node/node_metrics.d.ts.map +1 -0
  10. package/dest/aztec-node/node_metrics.js +36 -0
  11. package/dest/aztec-node/node_public_calls_simulator.d.ts +108 -0
  12. package/dest/aztec-node/node_public_calls_simulator.d.ts.map +1 -0
  13. package/dest/aztec-node/node_public_calls_simulator.js +380 -0
  14. package/dest/aztec-node/public_data_overrides.d.ts +13 -0
  15. package/dest/aztec-node/public_data_overrides.d.ts.map +1 -0
  16. package/dest/aztec-node/public_data_overrides.js +21 -0
  17. package/dest/aztec-node/register_node_rpc_handlers.d.ts +11 -0
  18. package/dest/aztec-node/register_node_rpc_handlers.d.ts.map +1 -0
  19. package/dest/aztec-node/register_node_rpc_handlers.js +48 -0
  20. package/dest/aztec-node/server.d.ts +281 -0
  21. package/dest/aztec-node/server.d.ts.map +1 -0
  22. package/dest/aztec-node/server.js +1235 -0
  23. package/dest/bin/index.d.ts +3 -0
  24. package/dest/bin/index.d.ts.map +1 -0
  25. package/dest/bin/index.js +57 -0
  26. package/dest/factory.d.ts +33 -0
  27. package/dest/factory.d.ts.map +1 -0
  28. package/dest/factory.js +539 -0
  29. package/dest/index.d.ts +5 -0
  30. package/dest/index.d.ts.map +1 -0
  31. package/dest/index.js +4 -0
  32. package/dest/modules/block_parameter.d.ts +25 -0
  33. package/dest/modules/block_parameter.d.ts.map +1 -0
  34. package/dest/modules/block_parameter.js +100 -0
  35. package/dest/modules/node_block_provider.d.ts +19 -0
  36. package/dest/modules/node_block_provider.d.ts.map +1 -0
  37. package/dest/modules/node_block_provider.js +112 -0
  38. package/dest/modules/node_tx_receipt.d.ts +24 -0
  39. package/dest/modules/node_tx_receipt.d.ts.map +1 -0
  40. package/dest/modules/node_tx_receipt.js +70 -0
  41. package/dest/modules/node_world_state_queries.d.ts +65 -0
  42. package/dest/modules/node_world_state_queries.d.ts.map +1 -0
  43. package/dest/modules/node_world_state_queries.js +270 -0
  44. package/dest/sentinel/config.d.ts +9 -0
  45. package/dest/sentinel/config.d.ts.map +1 -0
  46. package/dest/sentinel/config.js +39 -0
  47. package/dest/sentinel/factory.d.ts +11 -0
  48. package/dest/sentinel/factory.d.ts.map +1 -0
  49. package/dest/sentinel/factory.js +24 -0
  50. package/dest/sentinel/index.d.ts +3 -0
  51. package/dest/sentinel/index.d.ts.map +1 -0
  52. package/dest/sentinel/index.js +1 -0
  53. package/dest/sentinel/sentinel.d.ts +217 -0
  54. package/dest/sentinel/sentinel.d.ts.map +1 -0
  55. package/dest/sentinel/sentinel.js +551 -0
  56. package/dest/sentinel/store.d.ts +35 -0
  57. package/dest/sentinel/store.d.ts.map +1 -0
  58. package/dest/sentinel/store.js +182 -0
  59. package/dest/test/index.d.ts +31 -0
  60. package/dest/test/index.d.ts.map +1 -0
  61. package/dest/test/index.js +1 -0
  62. package/package.json +118 -0
  63. package/src/aztec-node/block_response_helpers.ts +161 -0
  64. package/src/aztec-node/config.ts +216 -0
  65. package/src/aztec-node/node_metrics.ts +49 -0
  66. package/src/aztec-node/node_public_calls_simulator.ts +437 -0
  67. package/src/aztec-node/public_data_overrides.ts +35 -0
  68. package/src/aztec-node/register_node_rpc_handlers.ts +45 -0
  69. package/src/aztec-node/server.ts +1155 -0
  70. package/src/bin/index.ts +77 -0
  71. package/src/factory.ts +704 -0
  72. package/src/index.ts +4 -0
  73. package/src/modules/block_parameter.ts +93 -0
  74. package/src/modules/node_block_provider.ts +149 -0
  75. package/src/modules/node_tx_receipt.ts +115 -0
  76. package/src/modules/node_world_state_queries.ts +373 -0
  77. package/src/sentinel/README.md +103 -0
  78. package/src/sentinel/config.ts +49 -0
  79. package/src/sentinel/factory.ts +46 -0
  80. package/src/sentinel/index.ts +8 -0
  81. package/src/sentinel/sentinel.ts +694 -0
  82. package/src/sentinel/store.ts +193 -0
  83. package/src/test/index.ts +32 -0
@@ -0,0 +1,182 @@
1
+ import { EpochNumber, SlotNumber } from '@aztec-labs/foundation/branded-types';
2
+ import { EthAddress } from '@aztec-labs/foundation/eth-address';
3
+ import { BufferReader, numToUInt8, numToUInt32BE, serializeToBuffer } from '@aztec-labs/foundation/serialize';
4
+ export class SentinelStore {
5
+ store;
6
+ config;
7
+ static SCHEMA_VERSION = 4;
8
+ // a map from validator address to their ValidatorStatusHistory
9
+ historyMap;
10
+ // a map from validator address to their historical epoch performance, evaluated at end-of-epoch.
11
+ // e.g. { validator: [{ epoch: 1, missed: 1, total: 10 }, { epoch: 2, missed: 3, total: 7 }, ...] }
12
+ epochMap;
13
+ constructor(store, config){
14
+ this.store = store;
15
+ this.config = config;
16
+ this.historyMap = store.openMap('sentinel-validator-status');
17
+ this.epochMap = store.openMap('sentinel-validator-epoch');
18
+ }
19
+ getHistoryLength() {
20
+ return this.config.historyLength;
21
+ }
22
+ getHistoricEpochPerformanceLength() {
23
+ return this.config.historicEpochPerformanceLength;
24
+ }
25
+ async updateEpochPerformance(epoch, performance) {
26
+ await this.store.transactionAsync(async ()=>{
27
+ for (const [who, { missed, total }] of Object.entries(performance)){
28
+ await this.pushValidatorEpochPerformance({
29
+ who: EthAddress.fromString(who),
30
+ missed,
31
+ total,
32
+ epoch
33
+ });
34
+ }
35
+ });
36
+ }
37
+ async getEpochPerformance(who) {
38
+ const currentPerformanceBuffer = await this.epochMap.getAsync(who.toString());
39
+ return currentPerformanceBuffer ? this.deserializePerformance(currentPerformanceBuffer) : [];
40
+ }
41
+ async pushValidatorEpochPerformance({ who, missed, total, epoch }) {
42
+ const currentPerformance = await this.getEpochPerformance(who);
43
+ const existingIndex = currentPerformance.findIndex((p)=>p.epoch === epoch);
44
+ if (existingIndex !== -1) {
45
+ currentPerformance[existingIndex] = {
46
+ missed,
47
+ total,
48
+ epoch
49
+ };
50
+ } else {
51
+ currentPerformance.push({
52
+ missed,
53
+ total,
54
+ epoch
55
+ });
56
+ }
57
+ // This should be sorted by epoch, but just in case.
58
+ // Since we keep the size small, this is not a big deal.
59
+ currentPerformance.sort((a, b)=>Number(a.epoch - b.epoch));
60
+ // keep the most recent `historicEpochPerformanceLength` entries.
61
+ const performanceToKeep = currentPerformance.slice(-this.config.historicEpochPerformanceLength);
62
+ await this.epochMap.set(who.toString(), this.serializePerformance(performanceToKeep));
63
+ }
64
+ async updateValidators(slot, statuses) {
65
+ await this.store.transactionAsync(async ()=>{
66
+ for (const [who, status] of Object.entries(statuses)){
67
+ if (status) {
68
+ await this.pushValidatorStatusForSlot(EthAddress.fromString(who), slot, status);
69
+ }
70
+ }
71
+ });
72
+ }
73
+ async pushValidatorStatusForSlot(who, slot, status) {
74
+ await this.store.transactionAsync(async ()=>{
75
+ const currentHistory = await this.getHistory(who) ?? [];
76
+ const newHistory = [
77
+ ...currentHistory,
78
+ {
79
+ slot,
80
+ status
81
+ }
82
+ ].slice(-this.config.historyLength);
83
+ await this.historyMap.set(who.toString(), this.serializeHistory(newHistory));
84
+ });
85
+ }
86
+ async getHistories() {
87
+ const histories = {};
88
+ for await (const [address, history] of this.historyMap.entriesAsync()){
89
+ histories[address] = this.deserializeHistory(history);
90
+ }
91
+ return histories;
92
+ }
93
+ async getHistory(address) {
94
+ const data = await this.historyMap.getAsync(address.toString());
95
+ return data && this.deserializeHistory(data);
96
+ }
97
+ serializePerformance(performance) {
98
+ return serializeToBuffer(performance.map((p)=>[
99
+ numToUInt32BE(Number(p.epoch)),
100
+ numToUInt32BE(p.missed),
101
+ numToUInt32BE(p.total)
102
+ ]));
103
+ }
104
+ deserializePerformance(buffer) {
105
+ const reader = new BufferReader(buffer);
106
+ const performance = [];
107
+ while(!reader.isEmpty()){
108
+ performance.push({
109
+ epoch: EpochNumber(reader.readNumber()),
110
+ missed: reader.readNumber(),
111
+ total: reader.readNumber()
112
+ });
113
+ }
114
+ return performance;
115
+ }
116
+ serializeHistory(history) {
117
+ return serializeToBuffer(history.map((h)=>[
118
+ numToUInt32BE(Number(h.slot)),
119
+ numToUInt8(this.statusToNumber(h.status))
120
+ ]));
121
+ }
122
+ deserializeHistory(buffer) {
123
+ const reader = new BufferReader(buffer);
124
+ const history = [];
125
+ while(!reader.isEmpty()){
126
+ const slot = SlotNumber(reader.readNumber());
127
+ const status = this.statusFromNumber(reader.readUInt8());
128
+ history.push({
129
+ slot,
130
+ status
131
+ });
132
+ }
133
+ return history;
134
+ }
135
+ statusToNumber(status) {
136
+ switch(status){
137
+ case 'checkpoint-mined':
138
+ return 1;
139
+ case 'checkpoint-valid':
140
+ return 2;
141
+ case 'checkpoint-missed':
142
+ return 3;
143
+ case 'attestation-sent':
144
+ return 4;
145
+ case 'attestation-missed':
146
+ return 5;
147
+ case 'blocks-missed':
148
+ return 6;
149
+ case 'checkpoint-invalid':
150
+ return 7;
151
+ case 'checkpoint-unvalidated':
152
+ return 8;
153
+ default:
154
+ {
155
+ const _exhaustive = status;
156
+ throw new Error(`Unknown status: ${status}`);
157
+ }
158
+ }
159
+ }
160
+ statusFromNumber(status) {
161
+ switch(status){
162
+ case 1:
163
+ return 'checkpoint-mined';
164
+ case 2:
165
+ return 'checkpoint-valid';
166
+ case 3:
167
+ return 'checkpoint-missed';
168
+ case 4:
169
+ return 'attestation-sent';
170
+ case 5:
171
+ return 'attestation-missed';
172
+ case 6:
173
+ return 'blocks-missed';
174
+ case 7:
175
+ return 'checkpoint-invalid';
176
+ case 8:
177
+ return 'checkpoint-unvalidated';
178
+ default:
179
+ throw new Error(`Unknown status: ${status}`);
180
+ }
181
+ }
182
+ }
@@ -0,0 +1,31 @@
1
+ import type { EpochCacheInterface } from '@aztec-labs/epoch-cache';
2
+ import type { P2P } from '@aztec-labs/p2p';
3
+ import { SequencerClient } from '@aztec-labs/sequencer-client';
4
+ import { DataWithholdingWatcher, type SlasherClientInterface } from '@aztec-labs/slasher';
5
+ import type { L2BlockSource } from '@aztec-labs/stdlib/block';
6
+ import type { ContractDataSource } from '@aztec-labs/stdlib/contract';
7
+ import type { L2LogsSource, Service, WorldStateSynchronizer } from '@aztec-labs/stdlib/interfaces/server';
8
+ import type { L1ToL2MessageSource } from '@aztec-labs/stdlib/messaging';
9
+ import type { GlobalVariableBuilder as GlobalVariableBuilderInterface } from '@aztec-labs/stdlib/tx';
10
+ import type { AztecNodeConfig } from '../aztec-node/config.js';
11
+ import { AztecNodeService } from '../aztec-node/server.js';
12
+ import { Sentinel } from '../sentinel/sentinel.js';
13
+ export declare class TestAztecNodeService extends AztecNodeService {
14
+ config: AztecNodeConfig;
15
+ p2pClient: P2P;
16
+ blockSource: L2BlockSource & Partial<Service>;
17
+ logsSource: L2LogsSource;
18
+ contractDataSource: ContractDataSource;
19
+ l1ToL2MessageSource: L1ToL2MessageSource;
20
+ worldStateSynchronizer: WorldStateSynchronizer;
21
+ sequencer: SequencerClient | undefined;
22
+ slasherClient: SlasherClientInterface | undefined;
23
+ validatorsSentinel: Sentinel | undefined;
24
+ dataWithholdingWatcher: DataWithholdingWatcher | undefined;
25
+ l1ChainId: number;
26
+ version: number;
27
+ globalVariableBuilder: GlobalVariableBuilderInterface;
28
+ epochCache: EpochCacheInterface;
29
+ packageVersion: string;
30
+ }
31
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZXN0L2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLG1CQUFtQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDbkUsT0FBTyxLQUFLLEVBQUUsR0FBRyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQy9ELE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxLQUFLLHNCQUFzQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDMUYsT0FBTyxLQUFLLEVBQUUsYUFBYSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDOUQsT0FBTyxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUN0RSxPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDMUcsT0FBTyxLQUFLLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUN4RSxPQUFPLEtBQUssRUFBRSxxQkFBcUIsSUFBSSw4QkFBOEIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRXJHLE9BQU8sS0FBSyxFQUFFLGVBQWUsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQy9ELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzNELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUVuRCxNQUFNLENBQUMsT0FBTyxPQUFPLG9CQUFxQixTQUFRLGdCQUFnQjtJQUNqRCxNQUFNLEVBQUUsZUFBZSxDQUFDO0lBQ3hCLFNBQVMsRUFBRSxHQUFHLENBQUM7SUFDZixXQUFXLEVBQUUsYUFBYSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM5QyxVQUFVLEVBQUUsWUFBWSxDQUFDO0lBQ3pCLGtCQUFrQixFQUFFLGtCQUFrQixDQUFDO0lBQ3ZDLG1CQUFtQixFQUFFLG1CQUFtQixDQUFDO0lBQ3pDLHNCQUFzQixFQUFFLHNCQUFzQixDQUFDO0lBQy9DLFNBQVMsRUFBRSxlQUFlLEdBQUcsU0FBUyxDQUFDO0lBQ3ZDLGFBQWEsRUFBRSxzQkFBc0IsR0FBRyxTQUFTLENBQUM7SUFDbEQsa0JBQWtCLEVBQUUsUUFBUSxHQUFHLFNBQVMsQ0FBQztJQUN6QyxzQkFBc0IsRUFBRSxzQkFBc0IsR0FBRyxTQUFTLENBQUM7SUFDM0QsU0FBUyxFQUFFLE1BQU0sQ0FBQztJQUNsQixPQUFPLEVBQUUsTUFBTSxDQUFDO0lBQ2hCLHFCQUFxQixFQUFFLDhCQUE4QixDQUFDO0lBQ3RELFVBQVUsRUFBRSxtQkFBbUIsQ0FBQztJQUNoQyxjQUFjLEVBQUUsTUFBTSxDQUFDO0NBQ3ZDIn0=
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,KAAK,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC1F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAC1G,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,KAAK,EAAE,qBAAqB,IAAI,8BAA8B,EAAE,MAAM,uBAAuB,CAAC;AAErG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,MAAM,CAAC,OAAO,OAAO,oBAAqB,SAAQ,gBAAgB;IACjD,MAAM,EAAE,eAAe,CAAC;IACxB,SAAS,EAAE,GAAG,CAAC;IACf,WAAW,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,UAAU,EAAE,YAAY,CAAC;IACzB,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,sBAAsB,EAAE,sBAAsB,CAAC;IAC/C,SAAS,EAAE,eAAe,GAAG,SAAS,CAAC;IACvC,aAAa,EAAE,sBAAsB,GAAG,SAAS,CAAC;IAClD,kBAAkB,EAAE,QAAQ,GAAG,SAAS,CAAC;IACzC,sBAAsB,EAAE,sBAAsB,GAAG,SAAS,CAAC;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,qBAAqB,EAAE,8BAA8B,CAAC;IACtD,UAAU,EAAE,mBAAmB,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC;CACvC"}
@@ -0,0 +1 @@
1
+ import { AztecNodeService } from '../aztec-node/server.js';
package/package.json ADDED
@@ -0,0 +1,118 @@
1
+ {
2
+ "name": "@aztec-labs/aztec-node",
3
+ "version": "6.0.0-nightly.20260829",
4
+ "main": "dest/index.js",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": "./dest/index.js",
8
+ "./config": "./dest/aztec-node/config.js",
9
+ "./sentinel": "./dest/aztec-node/sentinel.js",
10
+ "./test": "./dest/test/index.js"
11
+ },
12
+ "typedocOptions": {
13
+ "entryPoints": [
14
+ "./src/index.ts"
15
+ ],
16
+ "name": "Aztec Node",
17
+ "tsconfig": "./tsconfig.json"
18
+ },
19
+ "scripts": {
20
+ "start": "node --no-warnings ./dest/bin",
21
+ "start:debug": "node --no-warnings --inspect ./dest/bin",
22
+ "build": "yarn clean && ../scripts/tsc.sh",
23
+ "build:dev": "../scripts/tsc.sh --watch",
24
+ "clean": "rm -rf ./dest .tsbuildinfo",
25
+ "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}"
26
+ },
27
+ "inherits": [
28
+ "../package.common.json"
29
+ ],
30
+ "jest": {
31
+ "extensionsToTreatAsEsm": [
32
+ ".ts"
33
+ ],
34
+ "transform": {
35
+ "^.+\\.tsx?$": [
36
+ "@swc/jest",
37
+ {
38
+ "jsc": {
39
+ "parser": {
40
+ "syntax": "typescript",
41
+ "decorators": true
42
+ },
43
+ "transform": {
44
+ "decoratorVersion": "2022-03"
45
+ }
46
+ }
47
+ }
48
+ ]
49
+ },
50
+ "moduleNameMapper": {
51
+ "^(\\.{1,2}/.*)\\.[cm]?js$": "$1"
52
+ },
53
+ "testRegex": "./src/.*\\.test\\.(js|mjs|ts)$",
54
+ "rootDir": "./src",
55
+ "reporters": [
56
+ "default"
57
+ ],
58
+ "testTimeout": 120000,
59
+ "setupFiles": [
60
+ "../../foundation/src/jest/setup.mjs"
61
+ ],
62
+ "testEnvironment": "../../foundation/src/jest/env.mjs",
63
+ "setupFilesAfterEnv": [
64
+ "../../foundation/src/jest/setupAfterEnv.mjs"
65
+ ]
66
+ },
67
+ "dependencies": {
68
+ "@aztec-labs/archiver": "6.0.0-nightly.20260829",
69
+ "@aztec-labs/bb-prover": "6.0.0-nightly.20260829",
70
+ "@aztec-labs/blob-client": "6.0.0-nightly.20260829",
71
+ "@aztec-labs/blob-lib": "6.0.0-nightly.20260829",
72
+ "@aztec-labs/constants": "6.0.0-nightly.20260829",
73
+ "@aztec-labs/epoch-cache": "6.0.0-nightly.20260829",
74
+ "@aztec-labs/ethereum": "6.0.0-nightly.20260829",
75
+ "@aztec-labs/foundation": "6.0.0-nightly.20260829",
76
+ "@aztec-labs/kv-store": "6.0.0-nightly.20260829",
77
+ "@aztec-labs/node-keystore": "6.0.0-nightly.20260829",
78
+ "@aztec-labs/node-lib": "6.0.0-nightly.20260829",
79
+ "@aztec-labs/p2p": "6.0.0-nightly.20260829",
80
+ "@aztec-labs/protocol-contracts": "6.0.0-nightly.20260829",
81
+ "@aztec-labs/prover-client": "6.0.0-nightly.20260829",
82
+ "@aztec-labs/prover-node": "6.0.0-nightly.20260829",
83
+ "@aztec-labs/sequencer-client": "6.0.0-nightly.20260829",
84
+ "@aztec-labs/simulator": "6.0.0-nightly.20260829",
85
+ "@aztec-labs/slasher": "6.0.0-nightly.20260829",
86
+ "@aztec-labs/standard-contracts": "6.0.0-nightly.20260829",
87
+ "@aztec-labs/stdlib": "6.0.0-nightly.20260829",
88
+ "@aztec-labs/telemetry-client": "6.0.0-nightly.20260829",
89
+ "@aztec-labs/validator-client": "6.0.0-nightly.20260829",
90
+ "@aztec-labs/validator-ha-signer": "6.0.0-nightly.20260829",
91
+ "@aztec-labs/world-state": "6.0.0-nightly.20260829",
92
+ "@aztec/bb.js": "6.0.0-nightly.20260826",
93
+ "koa": "^2.16.1",
94
+ "koa-router": "^13.1.1",
95
+ "tslib": "^2.4.0",
96
+ "viem": "npm:@aztec/viem@2.38.2"
97
+ },
98
+ "devDependencies": {
99
+ "@aztec-labs/noir-protocol-circuits-types": "6.0.0-nightly.20260829",
100
+ "@jest/globals": "^30.0.0",
101
+ "@types/jest": "^30.0.0",
102
+ "@types/node": "^22.15.17",
103
+ "@typescript/native-preview": "7.0.0-dev.20260113.1",
104
+ "jest": "^30.0.0",
105
+ "jest-mock-extended": "^4.0.0",
106
+ "ts-node": "^10.9.1",
107
+ "typescript": "^5.3.3"
108
+ },
109
+ "files": [
110
+ "dest",
111
+ "src",
112
+ "!*.test.*"
113
+ ],
114
+ "types": "./dest/index.d.ts",
115
+ "engines": {
116
+ "node": ">=20.10"
117
+ }
118
+ }
@@ -0,0 +1,161 @@
1
+ import { BlockNumber } from '@aztec-labs/foundation/branded-types';
2
+ import { type BlockData, type CommitteeAttestation, L2Block } from '@aztec-labs/stdlib/block';
3
+ import type {
4
+ CheckpointData,
5
+ L1PublishedData,
6
+ ProposedCheckpointData,
7
+ PublishedCheckpoint,
8
+ } from '@aztec-labs/stdlib/checkpoint';
9
+ import {
10
+ type BlockIncludeOptions,
11
+ type BlockResponse,
12
+ type CheckpointIncludeOptions,
13
+ type CheckpointResponse,
14
+ l1PublishInfoFromL1PublishedData,
15
+ } from '@aztec-labs/stdlib/interfaces/client';
16
+
17
+ /** Projects a full {@link L2Block} into a {@link BlockResponse}, attaching L1 / attestation context when provided. */
18
+ export async function blockResponseFromL2Block(
19
+ block: L2Block,
20
+ options: BlockIncludeOptions,
21
+ context?: { l1?: L1PublishedData; attestations?: CommitteeAttestation[] },
22
+ ): Promise<BlockResponse> {
23
+ const response: BlockResponse = {
24
+ header: block.header,
25
+ archive: block.archive,
26
+ hash: await block.hash(),
27
+ checkpointNumber: block.checkpointNumber,
28
+ indexWithinCheckpoint: block.indexWithinCheckpoint,
29
+ number: block.number,
30
+ };
31
+ if (options.includeTransactions) {
32
+ (response as BlockResponse).body = block.body;
33
+ }
34
+ if (options.includeL1PublishInfo) {
35
+ (response as BlockResponse).l1 = l1PublishInfoFromL1PublishedData(context?.l1);
36
+ }
37
+ if (options.includeAttestations) {
38
+ (response as BlockResponse).attestations = context?.attestations ?? [];
39
+ }
40
+ return response;
41
+ }
42
+
43
+ /** Projects metadata-only {@link BlockData} into a {@link BlockResponse}. */
44
+ export function blockResponseFromBlockData(
45
+ data: BlockData,
46
+ options: BlockIncludeOptions,
47
+ context?: { l1?: L1PublishedData; attestations?: CommitteeAttestation[] },
48
+ ): BlockResponse {
49
+ const response: BlockResponse = {
50
+ header: data.header,
51
+ archive: data.archive,
52
+ hash: data.blockHash,
53
+ checkpointNumber: data.checkpointNumber,
54
+ indexWithinCheckpoint: data.indexWithinCheckpoint,
55
+ number: data.header.getBlockNumber(),
56
+ };
57
+ if (options.includeL1PublishInfo) {
58
+ (response as BlockResponse).l1 = l1PublishInfoFromL1PublishedData(context?.l1);
59
+ }
60
+ if (options.includeAttestations) {
61
+ (response as BlockResponse).attestations = context?.attestations ?? [];
62
+ }
63
+ return response;
64
+ }
65
+
66
+ /** Projects a {@link PublishedCheckpoint} into a {@link CheckpointResponse}. */
67
+ export async function checkpointResponseFromPublishedCheckpoint(
68
+ pc: PublishedCheckpoint,
69
+ options: CheckpointIncludeOptions,
70
+ ): Promise<CheckpointResponse> {
71
+ const response: CheckpointResponse = {
72
+ number: pc.checkpoint.number,
73
+ header: pc.checkpoint.header,
74
+ archive: pc.checkpoint.archive,
75
+ checkpointOutHash: pc.checkpoint.getCheckpointOutHash(),
76
+ startBlock: pc.checkpoint.blocks[0]?.number ?? BlockNumber.ZERO,
77
+ blockCount: pc.checkpoint.blocks.length,
78
+ feeAssetPriceModifier: pc.checkpoint.feeAssetPriceModifier,
79
+ };
80
+ if (options.includeBlocks) {
81
+ (response as CheckpointResponse).blocks = await Promise.all(
82
+ pc.checkpoint.blocks.map(block =>
83
+ blockResponseFromL2Block(block, {
84
+ includeTransactions: options.includeTransactions,
85
+ includeL1PublishInfo: false,
86
+ includeAttestations: false,
87
+ }),
88
+ ),
89
+ );
90
+ }
91
+ if (options.includeL1PublishInfo) {
92
+ (response as CheckpointResponse).l1 = l1PublishInfoFromL1PublishedData(pc.l1);
93
+ }
94
+ if (options.includeAttestations) {
95
+ (response as CheckpointResponse).attestations = pc.attestations;
96
+ }
97
+ return response;
98
+ }
99
+
100
+ /** Projects metadata-only {@link CheckpointData} into a {@link CheckpointResponse}. `includeBlocks` is ignored (no blocks loaded). */
101
+ export function checkpointResponseFromCheckpointData(
102
+ cd: CheckpointData,
103
+ options: CheckpointIncludeOptions,
104
+ ): CheckpointResponse {
105
+ const response: CheckpointResponse = {
106
+ number: cd.checkpointNumber,
107
+ header: cd.header,
108
+ archive: cd.archive,
109
+ checkpointOutHash: cd.checkpointOutHash,
110
+ startBlock: cd.startBlock,
111
+ blockCount: cd.blockCount,
112
+ feeAssetPriceModifier: cd.feeAssetPriceModifier,
113
+ };
114
+ if (options.includeL1PublishInfo) {
115
+ (response as CheckpointResponse).l1 = l1PublishInfoFromL1PublishedData(cd.l1);
116
+ }
117
+ if (options.includeAttestations) {
118
+ (response as CheckpointResponse).attestations = cd.attestations;
119
+ }
120
+ return response;
121
+ }
122
+
123
+ /**
124
+ * Projects a {@link ProposedCheckpointData} into a {@link CheckpointResponse}.
125
+ * Pure projection — caller pre-fetches `blocks` via `blockSource.getBlocks(...)` when
126
+ * `options.includeBlocks` is true. Throws if `includeL1PublishInfo` or `includeAttestations`
127
+ * is requested (proposed checkpoints have no L1 publish info or attestations).
128
+ */
129
+ export async function projectProposedToCheckpointResponse(
130
+ proposed: ProposedCheckpointData,
131
+ options: CheckpointIncludeOptions,
132
+ blocks?: L2Block[],
133
+ ): Promise<CheckpointResponse> {
134
+ if (options.includeL1PublishInfo || options.includeAttestations) {
135
+ throw new Error('Proposed checkpoints have no L1 publish info or attestations');
136
+ }
137
+ const response: CheckpointResponse = {
138
+ number: proposed.checkpointNumber,
139
+ header: proposed.header,
140
+ archive: proposed.archive,
141
+ checkpointOutHash: proposed.checkpointOutHash,
142
+ startBlock: proposed.startBlock,
143
+ blockCount: proposed.blockCount,
144
+ feeAssetPriceModifier: proposed.feeAssetPriceModifier,
145
+ };
146
+ if (options.includeBlocks) {
147
+ if (!blocks) {
148
+ throw new Error('Blocks must be supplied when includeBlocks is true');
149
+ }
150
+ (response as CheckpointResponse).blocks = await Promise.all(
151
+ blocks.map(block =>
152
+ blockResponseFromL2Block(block, {
153
+ includeTransactions: options.includeTransactions,
154
+ includeL1PublishInfo: false,
155
+ includeAttestations: false,
156
+ }),
157
+ ),
158
+ );
159
+ }
160
+ return response;
161
+ }