@aztec/aztec 0.75.0-commit.c03ba01a2a4122e43e90d5133ba017e54b90e9d2
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/README.md +57 -0
- package/dest/bin/index.js +46 -0
- package/dest/cli/aztec_start_action.js +110 -0
- package/dest/cli/aztec_start_options.js +341 -0
- package/dest/cli/cli.js +33 -0
- package/dest/cli/cmds/start_archiver.js +35 -0
- package/dest/cli/cmds/start_bot.js +31 -0
- package/dest/cli/cmds/start_faucet.js +20 -0
- package/dest/cli/cmds/start_node.js +109 -0
- package/dest/cli/cmds/start_p2p_bootstrap.js +20 -0
- package/dest/cli/cmds/start_proof_verifier.js +12 -0
- package/dest/cli/cmds/start_prover_agent.js +32 -0
- package/dest/cli/cmds/start_prover_broker.js +22 -0
- package/dest/cli/cmds/start_prover_node.js +81 -0
- package/dest/cli/cmds/start_pxe.js +90 -0
- package/dest/cli/cmds/start_txe.js +11 -0
- package/dest/cli/index.js +1 -0
- package/dest/cli/util.js +154 -0
- package/dest/cli/validation.js +25 -0
- package/dest/examples/token.js +53 -0
- package/dest/examples/util.js +31 -0
- package/dest/index.js +1 -0
- package/dest/mnemonic.js +1 -0
- package/dest/sandbox.js +116 -0
- package/dest/splash.js +2 -0
- package/package.json +119 -0
- package/src/bin/index.ts +54 -0
- package/src/cli/aztec_start_action.ts +115 -0
- package/src/cli/aztec_start_options.ts +366 -0
- package/src/cli/cli.ts +48 -0
- package/src/cli/cmds/start_archiver.ts +47 -0
- package/src/cli/cmds/start_bot.ts +49 -0
- package/src/cli/cmds/start_faucet.ts +34 -0
- package/src/cli/cmds/start_node.ts +123 -0
- package/src/cli/cmds/start_p2p_bootstrap.ts +25 -0
- package/src/cli/cmds/start_proof_verifier.ts +18 -0
- package/src/cli/cmds/start_prover_agent.ts +65 -0
- package/src/cli/cmds/start_prover_broker.ts +37 -0
- package/src/cli/cmds/start_prover_node.ts +100 -0
- package/src/cli/cmds/start_pxe.ts +124 -0
- package/src/cli/cmds/start_txe.ts +15 -0
- package/src/cli/index.ts +1 -0
- package/src/cli/util.ts +216 -0
- package/src/cli/validation.ts +38 -0
- package/src/examples/token.ts +74 -0
- package/src/examples/util.ts +44 -0
- package/src/index.ts +1 -0
- package/src/mnemonic.ts +1 -0
- package/src/sandbox.ts +165 -0
- package/src/splash.ts +10 -0
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
import { type ArchiverConfig, archiverConfigMappings } from '@aztec/archiver/config';
|
|
2
|
+
import { faucetConfigMapping } from '@aztec/aztec-faucet/config';
|
|
3
|
+
import { sequencerClientConfigMappings } from '@aztec/aztec-node/config';
|
|
4
|
+
import { blobSinkConfigMapping } from '@aztec/blob-sink/client';
|
|
5
|
+
import { botConfigMappings } from '@aztec/bot/config';
|
|
6
|
+
import {
|
|
7
|
+
type ConfigMapping,
|
|
8
|
+
type EnvVar,
|
|
9
|
+
booleanConfigHelper,
|
|
10
|
+
isBooleanConfigValue,
|
|
11
|
+
omitConfigMappings,
|
|
12
|
+
} from '@aztec/foundation/config';
|
|
13
|
+
import { bootnodeConfigMappings, p2pConfigMappings } from '@aztec/p2p/config';
|
|
14
|
+
import { proofVerifierConfigMappings } from '@aztec/proof-verifier/config';
|
|
15
|
+
import {
|
|
16
|
+
type ProverAgentConfig,
|
|
17
|
+
type ProverBrokerConfig,
|
|
18
|
+
proverAgentConfigMappings,
|
|
19
|
+
proverBrokerConfigMappings,
|
|
20
|
+
} from '@aztec/prover-client/broker';
|
|
21
|
+
import { proverNodeConfigMappings } from '@aztec/prover-node/config';
|
|
22
|
+
import { allPxeConfigMappings } from '@aztec/pxe/config';
|
|
23
|
+
import { telemetryClientConfigMappings } from '@aztec/telemetry-client';
|
|
24
|
+
|
|
25
|
+
import { DefaultMnemonic } from '../mnemonic.js';
|
|
26
|
+
|
|
27
|
+
// Define an interface for options
|
|
28
|
+
export interface AztecStartOption {
|
|
29
|
+
flag: string;
|
|
30
|
+
description: string;
|
|
31
|
+
defaultValue: any | undefined;
|
|
32
|
+
printDefault?: (val: any) => string;
|
|
33
|
+
envVar: EnvVar | undefined;
|
|
34
|
+
parseVal?: (val: string) => any;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const getOptions = (namespace: string, configMappings: Record<string, ConfigMapping>) => {
|
|
38
|
+
const options: AztecStartOption[] = [];
|
|
39
|
+
for (const [key, { env, defaultValue: def, parseEnv, description, printDefault }] of Object.entries(configMappings)) {
|
|
40
|
+
if (universalOptions.includes(key)) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
const isBoolean = isBooleanConfigValue(configMappings, key as keyof typeof configMappings);
|
|
44
|
+
options.push({
|
|
45
|
+
flag: `--${namespace}.${key}${isBoolean ? '' : ' <value>'}`,
|
|
46
|
+
description,
|
|
47
|
+
defaultValue: def,
|
|
48
|
+
printDefault,
|
|
49
|
+
envVar: env,
|
|
50
|
+
parseVal: parseEnv,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
return options;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// These are options used by multiple modules so should be inputted once
|
|
57
|
+
export const universalOptions = ['l1RpcUrl', 'l1ChainId', 'l1Contracts', 'p2pEnabled', 'dataDirectory'];
|
|
58
|
+
|
|
59
|
+
// Define categories and options
|
|
60
|
+
export const aztecStartOptions: { [key: string]: AztecStartOption[] } = {
|
|
61
|
+
SANDBOX: [
|
|
62
|
+
{
|
|
63
|
+
flag: '--sandbox',
|
|
64
|
+
description: 'Starts Aztec Sandbox',
|
|
65
|
+
defaultValue: undefined,
|
|
66
|
+
envVar: undefined,
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
flag: '--sandbox.testAccounts',
|
|
70
|
+
description: 'Deploy test accounts on sandbox start',
|
|
71
|
+
envVar: 'TEST_ACCOUNTS',
|
|
72
|
+
...booleanConfigHelper(true),
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
flag: '--sandbox.noPXE',
|
|
76
|
+
description: 'Do not expose PXE service on sandbox start',
|
|
77
|
+
envVar: 'NO_PXE',
|
|
78
|
+
...booleanConfigHelper(),
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
API: [
|
|
82
|
+
{
|
|
83
|
+
flag: '--port <value>',
|
|
84
|
+
description: 'Port to run the Aztec Services on on',
|
|
85
|
+
defaultValue: 8080,
|
|
86
|
+
envVar: 'AZTEC_PORT',
|
|
87
|
+
parseVal: val => parseInt(val, 10),
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
flag: '--api-prefix <value>',
|
|
91
|
+
description: 'Prefix for API routes on any service that is started',
|
|
92
|
+
defaultValue: '',
|
|
93
|
+
envVar: 'API_PREFIX',
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
ETHEREUM: [
|
|
97
|
+
{
|
|
98
|
+
flag: '--l1-rpc-url <value>',
|
|
99
|
+
description: 'URL of the Ethereum RPC node that services will connect to',
|
|
100
|
+
defaultValue: 'http://localhost:8545',
|
|
101
|
+
envVar: 'ETHEREUM_HOST',
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
flag: '--l1-chain-id <value>',
|
|
105
|
+
description: 'The L1 chain ID',
|
|
106
|
+
defaultValue: 31337,
|
|
107
|
+
envVar: 'L1_CHAIN_ID',
|
|
108
|
+
parseVal: val => parseInt(val, 10),
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
flag: '--l1-mnemonic <value>',
|
|
112
|
+
description: 'Mnemonic for L1 accounts. Will be used if no publisher private keys are provided',
|
|
113
|
+
defaultValue: DefaultMnemonic,
|
|
114
|
+
envVar: 'MNEMONIC',
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
'L1 CONTRACT ADDRESSES': [
|
|
118
|
+
{
|
|
119
|
+
flag: '--rollup-address <value>',
|
|
120
|
+
description: 'The deployed L1 rollup contract address',
|
|
121
|
+
defaultValue: undefined,
|
|
122
|
+
envVar: 'ROLLUP_CONTRACT_ADDRESS',
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
flag: '--registry-address <value>',
|
|
126
|
+
description: 'The deployed L1 registry contract address',
|
|
127
|
+
defaultValue: undefined,
|
|
128
|
+
envVar: 'REGISTRY_CONTRACT_ADDRESS',
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
flag: '--inbox-address <value>',
|
|
132
|
+
description: 'The deployed L1 -> L2 inbox contract address',
|
|
133
|
+
defaultValue: undefined,
|
|
134
|
+
envVar: 'INBOX_CONTRACT_ADDRESS',
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
flag: '--outbox-address <value>',
|
|
138
|
+
description: 'The deployed L2 -> L1 outbox contract address',
|
|
139
|
+
defaultValue: undefined,
|
|
140
|
+
envVar: 'OUTBOX_CONTRACT_ADDRESS',
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
flag: '--fee-juice-address <value>',
|
|
144
|
+
description: 'The deployed L1 Fee Juice contract address',
|
|
145
|
+
defaultValue: undefined,
|
|
146
|
+
envVar: 'FEE_JUICE_CONTRACT_ADDRESS',
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
flag: '--staking-asset-address <value>',
|
|
150
|
+
description: 'The deployed L1 Staking Asset contract address',
|
|
151
|
+
defaultValue: undefined,
|
|
152
|
+
envVar: 'STAKING_ASSET_CONTRACT_ADDRESS',
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
flag: '--fee-juice-portal-address <value>',
|
|
156
|
+
description: 'The deployed L1 Fee Juice portal contract address',
|
|
157
|
+
defaultValue: undefined,
|
|
158
|
+
envVar: 'FEE_JUICE_PORTAL_CONTRACT_ADDRESS',
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
// We can't easily auto-generate node options as they're parts of modules defined below
|
|
162
|
+
'AZTEC NODE': [
|
|
163
|
+
{
|
|
164
|
+
flag: '--node',
|
|
165
|
+
description: 'Starts Aztec Node with options',
|
|
166
|
+
defaultValue: undefined,
|
|
167
|
+
envVar: undefined,
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
flag: '--data-directory <value>',
|
|
171
|
+
description: 'Where to store data. If not set, will store temporarily',
|
|
172
|
+
defaultValue: undefined,
|
|
173
|
+
envVar: 'DATA_DIRECTORY',
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
flag: '--node.archiverUrl <value>',
|
|
177
|
+
description: 'URL for an archiver service',
|
|
178
|
+
defaultValue: undefined,
|
|
179
|
+
envVar: 'ARCHIVER_URL',
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
flag: '--node.deployAztecContracts',
|
|
183
|
+
description: 'Deploys L1 Aztec contracts before starting the node. Needs mnemonic or private key to be set.',
|
|
184
|
+
envVar: 'DEPLOY_AZTEC_CONTRACTS',
|
|
185
|
+
...booleanConfigHelper(),
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
flag: '--node.deployAztecContractsSalt',
|
|
189
|
+
description:
|
|
190
|
+
'Numeric salt for deploying L1 Aztec contracts before starting the node. Needs mnemonic or private key to be set. Implies --node.deployAztecContracts.',
|
|
191
|
+
envVar: 'DEPLOY_AZTEC_CONTRACTS_SALT',
|
|
192
|
+
defaultValue: undefined,
|
|
193
|
+
parseVal: (val: string) => (val ? parseInt(val) : undefined),
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
flag: '--node.assumeProvenThroughBlockNumber',
|
|
197
|
+
description:
|
|
198
|
+
'Cheats the rollup contract into assuming every block until this one is proven. Useful for speeding up bootstraps.',
|
|
199
|
+
envVar: 'ASSUME_PROVEN_THROUGH_BLOCK_NUMBER',
|
|
200
|
+
parseVal: (val: string) => parseInt(val, 10),
|
|
201
|
+
defaultValue: 0,
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
flag: '--node.publisherPrivateKey <value>',
|
|
205
|
+
description: 'Private key of account for publishing L1 contracts',
|
|
206
|
+
defaultValue: undefined,
|
|
207
|
+
envVar: 'L1_PRIVATE_KEY',
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
flag: '--node.worldStateBlockCheckIntervalMS <value>',
|
|
211
|
+
description: 'Frequency in which to check for blocks in ms',
|
|
212
|
+
defaultValue: 100,
|
|
213
|
+
envVar: 'WS_BLOCK_CHECK_INTERVAL_MS',
|
|
214
|
+
parseVal: val => parseInt(val, 10),
|
|
215
|
+
},
|
|
216
|
+
],
|
|
217
|
+
'P2P SUBSYSTEM': [
|
|
218
|
+
{
|
|
219
|
+
flag: '--p2p-enabled',
|
|
220
|
+
description: 'Enable P2P subsystem',
|
|
221
|
+
envVar: 'P2P_ENABLED',
|
|
222
|
+
...booleanConfigHelper(),
|
|
223
|
+
},
|
|
224
|
+
...getOptions('p2p', p2pConfigMappings),
|
|
225
|
+
],
|
|
226
|
+
TELEMETRY: [...getOptions('tel', telemetryClientConfigMappings)],
|
|
227
|
+
PXE: [
|
|
228
|
+
{
|
|
229
|
+
flag: '--pxe',
|
|
230
|
+
description: 'Starts Aztec PXE with options',
|
|
231
|
+
defaultValue: undefined,
|
|
232
|
+
envVar: undefined,
|
|
233
|
+
},
|
|
234
|
+
...getOptions('pxe', allPxeConfigMappings),
|
|
235
|
+
],
|
|
236
|
+
ARCHIVER: [
|
|
237
|
+
{
|
|
238
|
+
flag: '--archiver',
|
|
239
|
+
description: 'Starts Aztec Archiver with options',
|
|
240
|
+
defaultValue: undefined,
|
|
241
|
+
envVar: undefined,
|
|
242
|
+
},
|
|
243
|
+
// filter out archiverUrl as it's passed separately in --node & --prover-node
|
|
244
|
+
...getOptions('archiver', archiverConfigMappings).filter(opt => !opt.flag.includes('archiverUrl')),
|
|
245
|
+
],
|
|
246
|
+
SEQUENCER: [
|
|
247
|
+
{
|
|
248
|
+
flag: '--sequencer',
|
|
249
|
+
description: 'Starts Aztec Sequencer with options',
|
|
250
|
+
defaultValue: undefined,
|
|
251
|
+
envVar: undefined,
|
|
252
|
+
},
|
|
253
|
+
...getOptions('sequencer', sequencerClientConfigMappings),
|
|
254
|
+
],
|
|
255
|
+
BLOB_SINK: [
|
|
256
|
+
{
|
|
257
|
+
flag: '--blob-sink',
|
|
258
|
+
description: 'Starts Aztec Blob Sink with options',
|
|
259
|
+
defaultValue: undefined,
|
|
260
|
+
envVar: undefined,
|
|
261
|
+
},
|
|
262
|
+
...getOptions('blobSink', blobSinkConfigMapping),
|
|
263
|
+
],
|
|
264
|
+
'PROVER NODE': [
|
|
265
|
+
{
|
|
266
|
+
flag: '--prover-node',
|
|
267
|
+
description: 'Starts Aztec Prover Node with options',
|
|
268
|
+
defaultValue: undefined,
|
|
269
|
+
envVar: undefined,
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
flag: '--proverNode.archiverUrl <value>',
|
|
273
|
+
description: 'URL for an archiver service',
|
|
274
|
+
defaultValue: undefined,
|
|
275
|
+
envVar: 'ARCHIVER_URL',
|
|
276
|
+
},
|
|
277
|
+
...getOptions(
|
|
278
|
+
'proverNode',
|
|
279
|
+
omitConfigMappings(proverNodeConfigMappings, [
|
|
280
|
+
// filter out options passed separately
|
|
281
|
+
...(Object.keys(archiverConfigMappings) as (keyof ArchiverConfig)[]),
|
|
282
|
+
...(Object.keys(proverBrokerConfigMappings) as (keyof ProverBrokerConfig)[]),
|
|
283
|
+
...(Object.keys(proverAgentConfigMappings) as (keyof ProverAgentConfig)[]),
|
|
284
|
+
]),
|
|
285
|
+
),
|
|
286
|
+
],
|
|
287
|
+
'PROVER BROKER': [
|
|
288
|
+
{
|
|
289
|
+
flag: '--prover-broker',
|
|
290
|
+
description: 'Starts Aztec proving job broker',
|
|
291
|
+
defaultValue: undefined,
|
|
292
|
+
envVar: undefined,
|
|
293
|
+
},
|
|
294
|
+
...getOptions(
|
|
295
|
+
'proverBroker',
|
|
296
|
+
// filter out archiver options from prover node options as they're passed separately in --archiver
|
|
297
|
+
proverBrokerConfigMappings,
|
|
298
|
+
),
|
|
299
|
+
],
|
|
300
|
+
'PROVER AGENT': [
|
|
301
|
+
{
|
|
302
|
+
flag: '--prover-agent',
|
|
303
|
+
description: 'Starts Aztec Prover Agent with options',
|
|
304
|
+
defaultValue: undefined,
|
|
305
|
+
envVar: undefined,
|
|
306
|
+
},
|
|
307
|
+
...getOptions('proverAgent', proverAgentConfigMappings),
|
|
308
|
+
],
|
|
309
|
+
'P2P BOOTSTRAP': [
|
|
310
|
+
{
|
|
311
|
+
flag: '--p2p-bootstrap',
|
|
312
|
+
description: 'Starts Aztec P2P Bootstrap with options',
|
|
313
|
+
defaultValue: undefined,
|
|
314
|
+
envVar: undefined,
|
|
315
|
+
},
|
|
316
|
+
...getOptions('p2pBootstrap', bootnodeConfigMappings),
|
|
317
|
+
],
|
|
318
|
+
BOT: [
|
|
319
|
+
{
|
|
320
|
+
flag: '--bot',
|
|
321
|
+
description: 'Starts Aztec Bot with options',
|
|
322
|
+
defaultValue: undefined,
|
|
323
|
+
envVar: undefined,
|
|
324
|
+
},
|
|
325
|
+
...getOptions('bot', botConfigMappings),
|
|
326
|
+
],
|
|
327
|
+
'PROOF VERIFIER': [
|
|
328
|
+
{
|
|
329
|
+
flag: '--proof-verifier',
|
|
330
|
+
description: 'Starts Aztec Proof Verifier with options',
|
|
331
|
+
defaultValue: undefined,
|
|
332
|
+
envVar: undefined,
|
|
333
|
+
},
|
|
334
|
+
...getOptions('proofVerifier', proofVerifierConfigMappings),
|
|
335
|
+
],
|
|
336
|
+
TXE: [
|
|
337
|
+
{
|
|
338
|
+
flag: '--txe',
|
|
339
|
+
description: 'Starts Aztec TXE with options',
|
|
340
|
+
defaultValue: undefined,
|
|
341
|
+
envVar: undefined,
|
|
342
|
+
},
|
|
343
|
+
],
|
|
344
|
+
FAUCET: [
|
|
345
|
+
{
|
|
346
|
+
flag: '--faucet',
|
|
347
|
+
description: 'Starts the Aztec faucet',
|
|
348
|
+
defaultValue: undefined,
|
|
349
|
+
envVar: undefined,
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
flag: '--faucet.apiServer',
|
|
353
|
+
description: 'Starts a simple HTTP server to access the faucet',
|
|
354
|
+
defaultValue: true,
|
|
355
|
+
envVar: undefined,
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
flag: '--faucet.apiServerPort <value>',
|
|
359
|
+
description: 'The port on which to start the api server on',
|
|
360
|
+
defaultValue: 8080,
|
|
361
|
+
envVar: undefined,
|
|
362
|
+
parseVal: val => parseInt(val, 10),
|
|
363
|
+
},
|
|
364
|
+
...getOptions('faucet', faucetConfigMapping),
|
|
365
|
+
],
|
|
366
|
+
};
|
package/src/cli/cli.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type LogFn, type Logger } from '@aztec/foundation/log';
|
|
2
|
+
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
|
|
5
|
+
import { aztecStartOptions } from './aztec_start_options.js';
|
|
6
|
+
import { addOptions, printAztecStartHelpText } from './util.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Returns commander program that defines the 'aztec' command line interface.
|
|
10
|
+
* @param userLog - log function for logging user output.
|
|
11
|
+
* @param debugLogger - logger for logging debug messages.
|
|
12
|
+
*/
|
|
13
|
+
export function injectAztecCommands(program: Command, userLog: LogFn, debugLogger: Logger): Command {
|
|
14
|
+
const startCmd = new Command('start').description(
|
|
15
|
+
'Starts Aztec modules. Options for each module can be set as key-value pairs (e.g. "option1=value1,option2=value2") or as environment variables.',
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
// Assuming commands are added elsewhere, here we just add options to the main program
|
|
19
|
+
Object.keys(aztecStartOptions).forEach(category => {
|
|
20
|
+
addOptions(startCmd, aztecStartOptions[category]);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
startCmd.helpInformation = printAztecStartHelpText;
|
|
24
|
+
|
|
25
|
+
startCmd.action(async options => {
|
|
26
|
+
const { aztecStart } = await import('./aztec_start_action.js');
|
|
27
|
+
return await aztecStart(options, userLog, debugLogger);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
program.addCommand(startCmd);
|
|
31
|
+
|
|
32
|
+
program.configureHelp({ sortSubcommands: true });
|
|
33
|
+
|
|
34
|
+
program.addHelpText(
|
|
35
|
+
'after',
|
|
36
|
+
`
|
|
37
|
+
|
|
38
|
+
Additional commands:
|
|
39
|
+
|
|
40
|
+
test [options]: starts a dockerized TXE node via
|
|
41
|
+
$ aztec start --txe
|
|
42
|
+
then runs
|
|
43
|
+
$ aztec-nargo test --silence-warnings --oracle-resolver=<TXE_ADDRESS> [options]
|
|
44
|
+
`,
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
return program;
|
|
48
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Archiver,
|
|
3
|
+
type ArchiverConfig,
|
|
4
|
+
KVArchiverDataStore,
|
|
5
|
+
archiverConfigMappings,
|
|
6
|
+
getArchiverConfigFromEnv,
|
|
7
|
+
} from '@aztec/archiver';
|
|
8
|
+
import { createLogger } from '@aztec/aztec.js';
|
|
9
|
+
import { createBlobSinkClient } from '@aztec/blob-sink/client';
|
|
10
|
+
import { ArchiverApiSchema } from '@aztec/circuit-types';
|
|
11
|
+
import { type NamespacedApiHandlers } from '@aztec/foundation/json-rpc/server';
|
|
12
|
+
import { type DataStoreConfig, dataConfigMappings } from '@aztec/kv-store/config';
|
|
13
|
+
import { createStore } from '@aztec/kv-store/lmdb-v2';
|
|
14
|
+
import { getConfigEnvVars as getTelemetryClientConfig, initTelemetryClient } from '@aztec/telemetry-client';
|
|
15
|
+
|
|
16
|
+
import { extractRelevantOptions } from '../util.js';
|
|
17
|
+
import { validateL1Config } from '../validation.js';
|
|
18
|
+
|
|
19
|
+
/** Starts a standalone archiver. */
|
|
20
|
+
export async function startArchiver(
|
|
21
|
+
options: any,
|
|
22
|
+
signalHandlers: (() => Promise<void>)[],
|
|
23
|
+
services: NamespacedApiHandlers,
|
|
24
|
+
) {
|
|
25
|
+
const archiverConfig = extractRelevantOptions<ArchiverConfig & DataStoreConfig>(
|
|
26
|
+
options,
|
|
27
|
+
{
|
|
28
|
+
...archiverConfigMappings,
|
|
29
|
+
...dataConfigMappings,
|
|
30
|
+
},
|
|
31
|
+
'archiver',
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
await validateL1Config({ ...getArchiverConfigFromEnv(), ...archiverConfig });
|
|
35
|
+
|
|
36
|
+
const storeLog = createLogger('archiver:lmdb');
|
|
37
|
+
const store = await createStore('archiver', archiverConfig, storeLog);
|
|
38
|
+
const archiverStore = new KVArchiverDataStore(store, archiverConfig.maxLogs);
|
|
39
|
+
|
|
40
|
+
const telemetry = initTelemetryClient(getTelemetryClientConfig());
|
|
41
|
+
// TODO(https://github.com/AztecProtocol/aztec-packages/issues/10056): place CL url in config here
|
|
42
|
+
const blobSinkClient = createBlobSinkClient();
|
|
43
|
+
const archiver = await Archiver.createAndSync(archiverConfig, archiverStore, { telemetry, blobSinkClient }, true);
|
|
44
|
+
services.archiver = [archiver, ArchiverApiSchema];
|
|
45
|
+
signalHandlers.push(archiver.stop);
|
|
46
|
+
return services;
|
|
47
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type BotConfig, BotRunner, botConfigMappings, getBotRunnerApiHandler } from '@aztec/bot';
|
|
2
|
+
import { type AztecNode, type PXE } from '@aztec/circuit-types';
|
|
3
|
+
import { type NamespacedApiHandlers } from '@aztec/foundation/json-rpc/server';
|
|
4
|
+
import { type LogFn } from '@aztec/foundation/log';
|
|
5
|
+
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
6
|
+
import { getConfigEnvVars as getTelemetryClientConfig, initTelemetryClient } from '@aztec/telemetry-client';
|
|
7
|
+
|
|
8
|
+
import { extractRelevantOptions } from '../util.js';
|
|
9
|
+
|
|
10
|
+
export async function startBot(
|
|
11
|
+
options: any,
|
|
12
|
+
signalHandlers: (() => Promise<void>)[],
|
|
13
|
+
services: NamespacedApiHandlers,
|
|
14
|
+
userLog: LogFn,
|
|
15
|
+
) {
|
|
16
|
+
const { proverNode, archiver, sequencer, p2pBootstrap, txe, prover } = options;
|
|
17
|
+
if (proverNode || archiver || sequencer || p2pBootstrap || txe || prover) {
|
|
18
|
+
userLog(
|
|
19
|
+
`Starting a bot with --prover-node, --prover, --archiver, --sequencer, --p2p-bootstrap, or --txe is not supported.`,
|
|
20
|
+
);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
// Start a PXE client that is used by the bot if required
|
|
24
|
+
let pxe: PXE | undefined;
|
|
25
|
+
if (options.pxe) {
|
|
26
|
+
const { addPXE } = await import('./start_pxe.js');
|
|
27
|
+
pxe = await addPXE(options, signalHandlers, services, userLog);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const telemetry = initTelemetryClient(getTelemetryClientConfig());
|
|
31
|
+
await addBot(options, signalHandlers, services, { pxe, telemetry });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function addBot(
|
|
35
|
+
options: any,
|
|
36
|
+
signalHandlers: (() => Promise<void>)[],
|
|
37
|
+
services: NamespacedApiHandlers,
|
|
38
|
+
deps: { pxe?: PXE; node?: AztecNode; telemetry: TelemetryClient },
|
|
39
|
+
) {
|
|
40
|
+
const config = extractRelevantOptions<BotConfig>(options, botConfigMappings, 'bot');
|
|
41
|
+
|
|
42
|
+
const botRunner = new BotRunner(config, deps);
|
|
43
|
+
if (!config.noStart) {
|
|
44
|
+
void botRunner.start(); // Do not block since bot setup takes time
|
|
45
|
+
}
|
|
46
|
+
services.bot = getBotRunnerApiHandler(botRunner);
|
|
47
|
+
signalHandlers.push(botRunner.stop);
|
|
48
|
+
return Promise.resolve();
|
|
49
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Faucet,
|
|
3
|
+
FaucetSchema,
|
|
4
|
+
createFaucetHttpServer,
|
|
5
|
+
faucetConfigMapping,
|
|
6
|
+
getFaucetConfigFromEnv,
|
|
7
|
+
} from '@aztec/aztec-faucet';
|
|
8
|
+
import { type NamespacedApiHandlers } from '@aztec/foundation/json-rpc/server';
|
|
9
|
+
import { type LogFn } from '@aztec/foundation/log';
|
|
10
|
+
|
|
11
|
+
import { extractNamespacedOptions, extractRelevantOptions } from '../util.js';
|
|
12
|
+
|
|
13
|
+
export async function startFaucet(
|
|
14
|
+
options: any,
|
|
15
|
+
signalHandlers: (() => Promise<void>)[],
|
|
16
|
+
services: NamespacedApiHandlers,
|
|
17
|
+
log: LogFn,
|
|
18
|
+
) {
|
|
19
|
+
const faucetOptions = extractNamespacedOptions(options, 'faucet');
|
|
20
|
+
const config = {
|
|
21
|
+
...getFaucetConfigFromEnv(),
|
|
22
|
+
...extractRelevantOptions(options, faucetConfigMapping, 'faucet'),
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const faucet = await Faucet.create(config);
|
|
26
|
+
if (faucetOptions.apiServer) {
|
|
27
|
+
const httpServer = createFaucetHttpServer(faucet);
|
|
28
|
+
httpServer.listen(faucetOptions.apiServerPort);
|
|
29
|
+
signalHandlers.push(() => new Promise(res => httpServer.close(() => res())));
|
|
30
|
+
log(`Faucet now running on port: ${faucetOptions.apiServerPort}`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
services.faucet = [faucet, FaucetSchema];
|
|
34
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { aztecNodeConfigMappings, getConfigEnvVars as getNodeConfigEnvVars } from '@aztec/aztec-node';
|
|
2
|
+
import { AztecNodeApiSchema, P2PApiSchema, type PXE } from '@aztec/circuit-types';
|
|
3
|
+
import { NULL_KEY } from '@aztec/ethereum';
|
|
4
|
+
import { type NamespacedApiHandlers } from '@aztec/foundation/json-rpc/server';
|
|
5
|
+
import { type LogFn } from '@aztec/foundation/log';
|
|
6
|
+
import {
|
|
7
|
+
type TelemetryClientConfig,
|
|
8
|
+
initTelemetryClient,
|
|
9
|
+
telemetryClientConfigMappings,
|
|
10
|
+
} from '@aztec/telemetry-client';
|
|
11
|
+
|
|
12
|
+
import { mnemonicToAccount, privateKeyToAccount } from 'viem/accounts';
|
|
13
|
+
|
|
14
|
+
import { createAztecNode, deployContractsToL1 } from '../../sandbox.js';
|
|
15
|
+
import { extractNamespacedOptions, extractRelevantOptions } from '../util.js';
|
|
16
|
+
import { validateL1Config } from '../validation.js';
|
|
17
|
+
|
|
18
|
+
export async function startNode(
|
|
19
|
+
options: any,
|
|
20
|
+
signalHandlers: (() => Promise<void>)[],
|
|
21
|
+
services: NamespacedApiHandlers,
|
|
22
|
+
userLog: LogFn,
|
|
23
|
+
) {
|
|
24
|
+
// options specifically namespaced with --node.<option>
|
|
25
|
+
const nodeSpecificOptions = extractNamespacedOptions(options, 'node');
|
|
26
|
+
// All options that are relevant to the Aztec Node
|
|
27
|
+
const nodeConfig = {
|
|
28
|
+
...extractRelevantOptions(options, aztecNodeConfigMappings, 'node'),
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
if (options.proverNode) {
|
|
32
|
+
userLog(`Running a Prover Node within a Node is not yet supported`);
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Deploy contracts if needed
|
|
37
|
+
if (nodeSpecificOptions.deployAztecContracts || nodeSpecificOptions.deployAztecContractsSalt) {
|
|
38
|
+
let account;
|
|
39
|
+
if (nodeSpecificOptions.publisherPrivateKey) {
|
|
40
|
+
account = privateKeyToAccount(nodeSpecificOptions.publisherPrivateKey);
|
|
41
|
+
} else if (options.l1Mnemonic) {
|
|
42
|
+
account = mnemonicToAccount(options.l1Mnemonic);
|
|
43
|
+
} else {
|
|
44
|
+
throw new Error('--node.publisherPrivateKey or --l1-mnemonic is required to deploy L1 contracts');
|
|
45
|
+
}
|
|
46
|
+
// REFACTOR: We should not be calling a method from sandbox on the prod start flow
|
|
47
|
+
await deployContractsToL1(nodeConfig, account!, undefined, {
|
|
48
|
+
assumeProvenThroughBlockNumber: nodeSpecificOptions.assumeProvenThroughBlockNumber,
|
|
49
|
+
salt: nodeSpecificOptions.deployAztecContractsSalt,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
// If not deploying, validate that the addresses and config provided are correct.
|
|
53
|
+
// Eventually, we should be able to dynamically load this just by having the L1 governance address,
|
|
54
|
+
// instead of only validating the config the user has entered.
|
|
55
|
+
else {
|
|
56
|
+
await validateL1Config({ ...getNodeConfigEnvVars(), ...nodeConfig });
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// if no publisher private key, then use l1Mnemonic
|
|
60
|
+
if (!options.archiver) {
|
|
61
|
+
// expect archiver url in node config
|
|
62
|
+
const archiverUrl = nodeConfig.archiverUrl;
|
|
63
|
+
if (!archiverUrl) {
|
|
64
|
+
userLog('Archiver Service URL is required to start Aztec Node without --archiver option');
|
|
65
|
+
throw new Error('Archiver Service URL is required to start Aztec Node without --archiver option');
|
|
66
|
+
}
|
|
67
|
+
nodeConfig.archiverUrl = archiverUrl;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (!options.sequencer) {
|
|
71
|
+
nodeConfig.disableValidator = true;
|
|
72
|
+
} else {
|
|
73
|
+
const sequencerConfig = extractNamespacedOptions(options, 'sequencer');
|
|
74
|
+
let account;
|
|
75
|
+
if (!sequencerConfig.publisherPrivateKey || sequencerConfig.publisherPrivateKey === NULL_KEY) {
|
|
76
|
+
if (!options.l1Mnemonic) {
|
|
77
|
+
userLog(
|
|
78
|
+
'--sequencer.publisherPrivateKey or --l1-mnemonic is required to start Aztec Node with --sequencer option',
|
|
79
|
+
);
|
|
80
|
+
throw new Error('Private key or Mnemonic is required to start Aztec Node with --sequencer option');
|
|
81
|
+
} else {
|
|
82
|
+
account = mnemonicToAccount(options.l1Mnemonic);
|
|
83
|
+
const privKey = account.getHdKey().privateKey;
|
|
84
|
+
nodeConfig.publisherPrivateKey = `0x${Buffer.from(privKey!).toString('hex')}`;
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
nodeConfig.publisherPrivateKey = sequencerConfig.publisherPrivateKey;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (nodeConfig.p2pEnabled) {
|
|
92
|
+
// ensure bootstrapNodes is an array
|
|
93
|
+
if (nodeConfig.bootstrapNodes && typeof nodeConfig.bootstrapNodes === 'string') {
|
|
94
|
+
nodeConfig.bootstrapNodes = (nodeConfig.bootstrapNodes as string).split(',');
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const telemetryConfig = extractRelevantOptions<TelemetryClientConfig>(options, telemetryClientConfigMappings, 'tel');
|
|
99
|
+
const telemetry = initTelemetryClient(telemetryConfig);
|
|
100
|
+
|
|
101
|
+
// Create and start Aztec Node
|
|
102
|
+
const node = await createAztecNode(nodeConfig, { telemetry });
|
|
103
|
+
|
|
104
|
+
// Add node and p2p to services list
|
|
105
|
+
services.node = [node, AztecNodeApiSchema];
|
|
106
|
+
services.p2p = [node.getP2P(), P2PApiSchema];
|
|
107
|
+
|
|
108
|
+
// Add node stop function to signal handlers
|
|
109
|
+
signalHandlers.push(node.stop.bind(node));
|
|
110
|
+
|
|
111
|
+
// Add a PXE client that connects to this node if requested
|
|
112
|
+
let pxe: PXE | undefined;
|
|
113
|
+
if (options.pxe) {
|
|
114
|
+
const { addPXE } = await import('./start_pxe.js');
|
|
115
|
+
pxe = await addPXE(options, signalHandlers, services, userLog, { node });
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Add a txs bot if requested
|
|
119
|
+
if (options.bot) {
|
|
120
|
+
const { addBot } = await import('./start_bot.js');
|
|
121
|
+
await addBot(options, signalHandlers, services, { pxe, node, telemetry });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { P2PBootstrapApiSchema } from '@aztec/circuit-types';
|
|
2
|
+
import { type NamespacedApiHandlers } from '@aztec/foundation/json-rpc/server';
|
|
3
|
+
import { type LogFn, createLogger } from '@aztec/foundation/log';
|
|
4
|
+
import { createStore } from '@aztec/kv-store/lmdb-v2';
|
|
5
|
+
import { type BootnodeConfig, BootstrapNode, bootnodeConfigMappings } from '@aztec/p2p';
|
|
6
|
+
import { getConfigEnvVars as getTelemetryClientConfig, initTelemetryClient } from '@aztec/telemetry-client';
|
|
7
|
+
|
|
8
|
+
import { extractRelevantOptions } from '../util.js';
|
|
9
|
+
|
|
10
|
+
export async function startP2PBootstrap(
|
|
11
|
+
options: any,
|
|
12
|
+
signalHandlers: (() => Promise<void>)[],
|
|
13
|
+
services: NamespacedApiHandlers,
|
|
14
|
+
userLog: LogFn,
|
|
15
|
+
) {
|
|
16
|
+
// Start a P2P bootstrap node.
|
|
17
|
+
const config = extractRelevantOptions<BootnodeConfig>(options, bootnodeConfigMappings, 'p2p');
|
|
18
|
+
const telemetryClient = initTelemetryClient(getTelemetryClientConfig());
|
|
19
|
+
const store = await createStore('p2p-bootstrap', config, createLogger('p2p:bootstrap:store'));
|
|
20
|
+
const node = new BootstrapNode(store, telemetryClient);
|
|
21
|
+
await node.start(config);
|
|
22
|
+
signalHandlers.push(() => node.stop());
|
|
23
|
+
services.bootstrap = [node, P2PBootstrapApiSchema];
|
|
24
|
+
userLog(`P2P bootstrap node started on ${config.udpListenAddress}`);
|
|
25
|
+
}
|