@aztec-labs/cli 6.0.0-rc.1 → 6.0.0-rc.3

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.
@@ -1,4 +1,4 @@
1
1
  import type { LogFn, Logger } from '@aztec-labs/foundation/log';
2
2
  import { type Command } from 'commander';
3
3
  export declare function injectCommands(program: Command, log: LogFn, debugLogger: Logger): Command;
4
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbWRzL2wxL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsS0FBSyxPQUFPLEVBQVUsTUFBTSxXQUFXLENBQUM7QUF1QmpELHdCQUFnQixjQUFjLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxNQUFNLFdBNmdCL0UifQ==
4
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbWRzL2wxL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsS0FBSyxPQUFPLEVBQVUsTUFBTSxXQUFXLENBQUM7QUF3QmpELHdCQUFnQixjQUFjLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxNQUFNLFdBbW1CL0UifQ==
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cmds/l1/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,WAAW,CAAC;AAuBjD,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,WA6gB/E"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cmds/l1/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,WAAW,CAAC;AAwBjD,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,WAmmB/E"}
@@ -1,7 +1,7 @@
1
1
  import { CheckpointNumber } from '@aztec-labs/foundation/branded-types';
2
2
  import { EthAddress } from '@aztec-labs/foundation/eth-address';
3
3
  import { Option } from 'commander';
4
- import { ETHEREUM_HOSTS, MNEMONIC, PRIVATE_KEY, l1ChainIdOption, nodeOption, parseBigint, parseEthereumAddress } from '../../utils/commands.js';
4
+ import { ETHEREUM_HOSTS, MNEMONIC, PRIVATE_KEY, l1ChainIdOption, nodeOption, parseBigint, parseEthereumAddress, parseOptionalInteger } from '../../utils/commands.js';
5
5
  const l1RpcUrlsOption = new Option('--l1-rpc-urls <string>', 'List of Ethereum host URLs. Chain identifiers localhost and testnet can be used (comma separated)').env('ETHEREUM_HOSTS').default([
6
6
  ETHEREUM_HOSTS
7
7
  ]).makeOptionMandatory(true).argParser((arg)=>arg.split(',').map((url)=>url.trim()));
@@ -99,7 +99,7 @@ export function injectCommands(program, log, debugLogger) {
99
99
  const account = generateL1Account();
100
100
  log(JSON.stringify(account, null, 2));
101
101
  });
102
- program.command('add-l1-validator').description('Adds a validator to the L1 rollup contract via a direct deposit.').addOption(l1RpcUrlsOption).addOption(networkOption).option('-pk, --private-key <string>', 'The private key to use sending the transaction', PRIVATE_KEY).option('-m, --mnemonic <string>', 'The mnemonic to use sending the transaction', 'test test test test test test test test test test test junk').addOption(l1ChainIdOption).option('--attester <address>', 'ethereum address of the attester', parseEthereumAddress).option('--withdrawer <address>', 'ethereum address of the withdrawer', parseEthereumAddress).option('--bls-secret-key <string>', 'The BN254 scalar field element used as a secret key for BLS signatures. Will be associated with the attester address.', parseBigint).option('--move-with-latest-rollup', 'Whether to move with the latest rollup', true).option('--rollup <string>', 'Rollup contract address', parseEthereumAddress).action(async (options)=>{
102
+ program.command('add-l1-validator').description('Adds a validator to the L1 rollup contract via a direct deposit.').addOption(l1RpcUrlsOption).addOption(networkOption).option('-pk, --private-key <string>', 'The private key to use sending the transaction', PRIVATE_KEY).option('-m, --mnemonic <string>', 'The mnemonic to use sending the transaction', 'test test test test test test test test test test test junk').addOption(l1ChainIdOption).option('--attester <address>', 'ethereum address of the attester', parseEthereumAddress).option('--withdrawer <address>', 'ethereum address of the withdrawer', parseEthereumAddress).option('--bls-secret-key <string>', 'The BN254 scalar field element used as a secret key for BLS signatures. Will be associated with the attester address.', parseBigint).option('--move-with-latest-rollup', 'Whether to move with the latest rollup', true).option('--no-move-with-latest-rollup', 'Keep the stake on this rollup after an upgrade').option('--rollup <string>', 'Rollup contract address', parseEthereumAddress).action(async (options)=>{
103
103
  const { addL1ValidatorViaRollup } = await import('./update_l1_validators.js');
104
104
  let rollupAddress = options.rollup;
105
105
  if (!rollupAddress) {
@@ -120,28 +120,67 @@ export function injectCommands(program, log, debugLogger) {
120
120
  debugLogger
121
121
  });
122
122
  });
123
- program.command('initiate-withdraw-by-attester').description("Initiates a withdrawal signed by the position's attester.").addOption(l1RpcUrlsOption).addOption(l1ChainIdOption).option('-pk, --private-key <string>', 'The attester private key', PRIVATE_KEY).option('-m, --mnemonic <string>', 'Mnemonic for the attester account', MNEMONIC).requiredOption('--attester <address>', 'Attester address of the position to exit', parseEthereumAddress).requiredOption('--rollup <address>', 'Rollup holding the position', parseEthereumAddress).action(async (options)=>{
123
+ addSignerOptions(program.command('initiate-withdraw-by-attester').description("Initiates a withdrawal signed by the position's attester."), 'attester').addOption(l1RpcUrlsOption).addOption(l1ChainIdOption).requiredOption('--attester <address>', 'Attester address of the position to exit', parseEthereumAddress).requiredOption('--rollup <address>', 'Rollup holding the position', parseEthereumAddress).action(async (options)=>{
124
124
  const { initiateWithdrawByAttester } = await import('./update_l1_validators.js');
125
125
  await initiateWithdrawByAttester({
126
126
  rpcUrls: options.l1RpcUrls,
127
127
  chainId: options.l1ChainId,
128
128
  privateKey: options.privateKey,
129
129
  mnemonic: options.mnemonic,
130
+ accountIndex: options.accountIndex,
131
+ addressIndex: options.addressIndex,
130
132
  attesterAddress: options.attester,
131
133
  rollupAddress: options.rollup,
132
134
  log,
133
135
  debugLogger
134
136
  });
135
137
  });
136
- program.command('initiate-withdraw-by-attester-batch').description('Relays a JSON array of attester-signed withdrawal authorizations.').addOption(l1RpcUrlsOption).addOption(l1ChainIdOption).option('-pk, --private-key <string>', 'The relayer private key', PRIVATE_KEY).option('-m, --mnemonic <string>', 'Mnemonic for the relayer account', MNEMONIC).requiredOption('--authorizations <path>', 'JSON file containing attester, decimal deadline, and signature fields').requiredOption('--rollup <address>', 'Rollup holding the positions', parseEthereumAddress).option('--up-to-limit', 'Process the largest permitted prefix instead of reverting when the whole batch is too large').action(async (options)=>{
138
+ addSignerOptions(program.command('sign-attester-exit').description('Signs an exit authorization locally and writes a JSON array for batch submission.'), 'attester').addOption(new Option('--l1-rpc-urls <string>', 'Ethereum host URLs (comma separated); when given, the chain ID they report must match, and they supply it or the rollup when those are not given').env('ETHEREUM_HOSTS').argParser((arg)=>arg.split(',').map((url)=>url.trim()))).addOption(new Option('-c, --l1-chain-id <number>', 'Chain ID to sign for; required unless --network or --l1-rpc-urls supplies it, and a value from L1_CHAIN_ID alone must be confirmed by one of them').env('L1_CHAIN_ID').argParser(Number)).addOption(networkOption).requiredOption('--attester <address>', 'Attester address of the position to exit', parseEthereumAddress).option('--rollup <address>', 'Rollup holding the position; defaults to the canonical rollup of --network', parseEthereumAddress).requiredOption('--deadline <timestamp>', 'Authorization expiry as Unix seconds', parseBigint).requiredOption('--output <path>', 'JSON output file (must be new unless --append is used)').option('--append', 'Append or create if missing, without validating existing authorizations; run initiate-withdraw-by-attester-batch --dry-run after the batch is complete').addHelpText('after', `
139
+ Examples:
140
+ aztec sign-attester-exit --private-key "$ATTESTER_KEY_0" --attester "$ATTESTER_0" --rollup "$ROLLUP" --l1-chain-id "$CHAIN_ID" --deadline "$DEADLINE" --output exits.json --append
141
+ aztec sign-attester-exit --private-key "$ATTESTER_KEY_1" --attester "$ATTESTER_1" --rollup "$ROLLUP" --l1-chain-id "$CHAIN_ID" --deadline "$DEADLINE" --output exits.json --append
142
+ aztec sign-attester-exit --mnemonic "$VALIDATOR_MNEMONIC" --account-index 0 --address-index 2 --attester "$ATTESTER_2" --rollup "$ROLLUP" --l1-chain-id "$CHAIN_ID" --deadline "$DEADLINE" --output exits.json --append
143
+ aztec sign-attester-exit --network testnet --l1-rpc-urls "$L1_RPC_URL" --private-key "$ATTESTER_KEY_3" --attester "$ATTESTER_3" --deadline "$DEADLINE" --output exits.json --append
144
+ aztec initiate-withdraw-by-attester-batch --dry-run --authorizations exits.json --rollup "$ROLLUP" --l1-chain-id "$CHAIN_ID" --l1-rpc-urls "$L1_RPC_URL"
145
+ aztec initiate-withdraw-by-attester-batch --authorizations exits.json --rollup "$ROLLUP" --l1-chain-id "$CHAIN_ID" --l1-rpc-urls "$L1_RPC_URL" --private-key "$RELAYER_PRIVATE_KEY"
146
+ Note: DEADLINE is a future Unix timestamp in seconds. Run append commands sequentially.
147
+ `).action(async (options, command)=>{
148
+ const { getAttesterExitNetwork, resolveAttesterExitTarget, signAttesterExit } = await import('./update_l1_validators.js');
149
+ const { chainId, rollupAddress } = await resolveAttesterExitTarget({
150
+ chainId: options.l1ChainId,
151
+ chainIdFromEnv: command.getOptionValueSource('l1ChainId') === 'env',
152
+ rpcUrls: options.l1RpcUrls,
153
+ network: options.network ? await getAttesterExitNetwork(options.network) : undefined,
154
+ rollupAddress: options.rollup,
155
+ log
156
+ });
157
+ await signAttesterExit({
158
+ rpcUrls: options.l1RpcUrls ?? [],
159
+ chainId,
160
+ privateKey: options.privateKey,
161
+ mnemonic: options.mnemonic,
162
+ accountIndex: options.accountIndex,
163
+ addressIndex: options.addressIndex,
164
+ attesterAddress: options.attester,
165
+ rollupAddress,
166
+ deadline: options.deadline,
167
+ output: options.output,
168
+ append: options.append,
169
+ log
170
+ });
171
+ });
172
+ addSignerOptions(program.command('initiate-withdraw-by-attester-batch').description('Relays a JSON array of attester-signed withdrawal authorizations.'), 'relayer').addOption(l1RpcUrlsOption).addOption(l1ChainIdOption).requiredOption('--authorizations <path>', 'JSON file containing attester, decimal deadline, and signature fields').requiredOption('--rollup <address>', 'Rollup holding the positions', parseEthereumAddress).option('--up-to-limit', 'Process the largest permitted prefix instead of reverting when the whole batch is too large').option('--dry-run', 'Simulate against current chain state without sending; no relayer key is required').action(async (options)=>{
137
173
  const { initiateWithdrawByAttesterBatch, readAttesterExitAuthorizations } = await import('./update_l1_validators.js');
138
174
  await initiateWithdrawByAttesterBatch({
139
175
  rpcUrls: options.l1RpcUrls,
140
176
  chainId: options.l1ChainId,
141
177
  privateKey: options.privateKey,
142
178
  mnemonic: options.mnemonic,
179
+ accountIndex: options.accountIndex,
180
+ addressIndex: options.addressIndex,
143
181
  authorizations: await readAttesterExitAuthorizations(options.authorizations),
144
182
  upToLimit: options.upToLimit,
183
+ dryRun: options.dryRun,
145
184
  rollupAddress: options.rollup,
146
185
  log,
147
186
  debugLogger
@@ -226,3 +265,17 @@ export function injectCommands(program, log, debugLogger) {
226
265
  });
227
266
  return program;
228
267
  }
268
+ function addSignerOptions(command, role) {
269
+ return command.addOption(new Option('-pk, --private-key <string>', `The ${role} private key; supply this or --mnemonic`).env('PRIVATE_KEY')).addOption(new Option('-m, --mnemonic <string>', `Mnemonic for the ${role} account; a flag overrides the other credential from the environment, and PRIVATE_KEY wins when both come from the environment`).env('MNEMONIC')).option('--account-index <number>', 'Mnemonic account index, matching validator-keys generation (default: 0; requires --mnemonic)', (value)=>parseOptionalInteger(value, 0)).option('--address-index <number>', role === 'attester' ? 'Mnemonic address index: validator-keys base address index + zero-based validator position; third validator = base + 2 (default: 0; requires --mnemonic)' : 'Mnemonic address index for the relayer paying for the transaction; attesters sign authorizations separately (default: 0; requires --mnemonic)', (value)=>parseOptionalInteger(value, 0)).hook('preAction', (_, actionCommand)=>{
270
+ const { privateKey, mnemonic } = actionCommand.opts();
271
+ if (!privateKey || !mnemonic) {
272
+ return;
273
+ }
274
+ // Only two credentials passed as flags are a conflict; otherwise drop the one that came from the environment.
275
+ if (actionCommand.getOptionValueSource('mnemonic') === 'env') {
276
+ actionCommand.setOptionValue('mnemonic', undefined);
277
+ } else if (actionCommand.getOptionValueSource('privateKey') === 'env') {
278
+ actionCommand.setOptionValue('privateKey', undefined);
279
+ }
280
+ });
281
+ }
@@ -0,0 +1,14 @@
1
+ import type { EthAddress } from '@aztec-labs/foundation/eth-address';
2
+ /**
3
+ * Starts a JSON-RPC server that reports `chainId` and, when `canonicalRollup` is given, answers every `eth_call` with
4
+ * that address and records the call. Any other method gets an error.
5
+ */
6
+ export declare function serveL1Rpc(chainId: number, canonicalRollup?: EthAddress): Promise<{
7
+ url: string;
8
+ registryCalls: {
9
+ to: string;
10
+ data: string;
11
+ }[];
12
+ close: () => Promise<unknown>;
13
+ }>;
14
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibDFfcnBjX3Rlc3RfdXRpbHMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbWRzL2wxL2wxX3JwY190ZXN0X3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBSXJFOzs7R0FHRztBQUNILHdCQUFzQixVQUFVLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxlQUFlLENBQUMsRUFBRSxVQUFVOzs7Ozs7O0dBa0M3RSJ9
@@ -0,0 +1 @@
1
+ {"version":3,"file":"l1_rpc_test_utils.d.ts","sourceRoot":"","sources":["../../../src/cmds/l1/l1_rpc_test_utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAIrE;;;GAGG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,UAAU;;;;;;;GAkC7E"}
@@ -0,0 +1,58 @@
1
+ import { createServer } from 'node:http';
2
+ import { encodeAbiParameters } from 'viem';
3
+ /**
4
+ * Starts a JSON-RPC server that reports `chainId` and, when `canonicalRollup` is given, answers every `eth_call` with
5
+ * that address and records the call. Any other method gets an error.
6
+ */ export async function serveL1Rpc(chainId, canonicalRollup) {
7
+ const registryCalls = [];
8
+ const server = createServer((request, response)=>{
9
+ let body = '';
10
+ request.on('data', (chunk)=>body += chunk);
11
+ request.on('end', ()=>{
12
+ const { id, method, params } = JSON.parse(body);
13
+ response.setHeader('content-type', 'application/json');
14
+ if (method === 'eth_chainId') {
15
+ response.end(JSON.stringify({
16
+ jsonrpc: '2.0',
17
+ id,
18
+ result: `0x${chainId.toString(16)}`
19
+ }));
20
+ } else if (method === 'eth_call' && canonicalRollup) {
21
+ registryCalls.push({
22
+ to: params[0].to,
23
+ data: params[0].data
24
+ });
25
+ response.end(JSON.stringify({
26
+ jsonrpc: '2.0',
27
+ id,
28
+ result: encodeAbiParameters([
29
+ {
30
+ type: 'address'
31
+ }
32
+ ], [
33
+ canonicalRollup.toString()
34
+ ])
35
+ }));
36
+ } else {
37
+ response.end(JSON.stringify({
38
+ jsonrpc: '2.0',
39
+ id,
40
+ error: {
41
+ code: -32601,
42
+ message: 'Unsupported method'
43
+ }
44
+ }));
45
+ }
46
+ });
47
+ });
48
+ await new Promise((resolve)=>server.listen(0, '127.0.0.1', resolve));
49
+ const address = server.address();
50
+ if (!address || typeof address === 'string') {
51
+ throw new Error('Expected a TCP server address');
52
+ }
53
+ return {
54
+ url: `http://127.0.0.1:${address.port}`,
55
+ registryCalls,
56
+ close: ()=>new Promise((resolve)=>server.close(resolve))
57
+ };
58
+ }
@@ -9,6 +9,13 @@ export interface RollupCommandArgs {
9
9
  rollupAddress: EthAddress;
10
10
  withdrawerAddress?: EthAddress;
11
11
  }
12
+ /** Credentials and derivation indices for a local Ethereum signer. */
13
+ export type SignerAccountArgs = {
14
+ privateKey?: string;
15
+ mnemonic?: string;
16
+ accountIndex?: number;
17
+ addressIndex?: number;
18
+ };
12
19
  export interface StakingAssetHandlerCommandArgs {
13
20
  rpcUrls: string[];
14
21
  chainId: number;
@@ -38,15 +45,51 @@ export declare function addL1ValidatorViaRollup({ rpcUrls, chainId, privateKey,
38
45
  export declare function removeL1Validator({ rpcUrls, chainId, privateKey, mnemonic, validatorAddress, rollupAddress, log, debugLogger }: RollupCommandArgs & LoggerArgs & {
39
46
  validatorAddress: EthAddress;
40
47
  }): Promise<void>;
48
+ /** Chain ID and registry published for a network; both are undefined when it publishes none, as for `local`. */
49
+ export type AttesterExitNetwork = {
50
+ name: string;
51
+ l1ChainId?: number;
52
+ registryAddress?: EthAddress;
53
+ };
54
+ /** Loads the published config of the network selected with --network, which takes precedence over the environment. */
55
+ export declare function getAttesterExitNetwork(name: string): Promise<AttesterExitNetwork>;
56
+ /** Inputs that select the chain and rollup an attester exit is signed for; each is undefined when not supplied. */
57
+ export type AttesterExitTargetArgs = {
58
+ chainId?: number;
59
+ /** Whether `chainId` came from the L1_CHAIN_ID environment variable rather than a flag. */
60
+ chainIdFromEnv?: boolean;
61
+ rpcUrls?: string[];
62
+ network?: AttesterExitNetwork;
63
+ rollupAddress?: EthAddress;
64
+ log: LogFn;
65
+ };
66
+ /**
67
+ * Resolves the chain ID and rollup an attester exit is signed for, without falling back to the Anvil chain ID.
68
+ * Whenever an RPC is given, its chain ID must match. Without one, signing is offline and needs the chain ID from a flag
69
+ * or --network; an L1_CHAIN_ID left in the environment alone is rejected because nothing confirms it.
70
+ */
71
+ export declare function resolveAttesterExitTarget({ chainId, chainIdFromEnv, rpcUrls, network, rollupAddress, log }: AttesterExitTargetArgs): Promise<{
72
+ chainId: number;
73
+ rollupAddress: EthAddress;
74
+ }>;
75
+ /** Signs an exit authorization locally and writes a JSON array accepted by the batch command. */
76
+ export declare function signAttesterExit({ rpcUrls, chainId, privateKey, mnemonic, accountIndex, addressIndex, rollupAddress, attesterAddress, deadline, output, append, log }: Omit<RollupCommandArgs, 'withdrawerAddress' | 'mnemonic' | 'privateKey'> & SignerAccountArgs & {
77
+ attesterAddress: EthAddress;
78
+ deadline: bigint;
79
+ output: string;
80
+ append?: boolean;
81
+ log: LogFn;
82
+ }): Promise<void>;
41
83
  /** Reads relayed attester exit authorizations from a JSON array. */
42
84
  export declare function readAttesterExitAuthorizations(path: string): Promise<AttesterExitAuthorization[]>;
43
85
  /** Relays a batch of attester-signed exits. */
44
- export declare function initiateWithdrawByAttesterBatch({ rpcUrls, chainId, privateKey, mnemonic, authorizations, upToLimit, rollupAddress, log, debugLogger }: Omit<RollupCommandArgs, 'withdrawerAddress'> & LoggerArgs & {
86
+ export declare function initiateWithdrawByAttesterBatch({ rpcUrls, chainId, privateKey, mnemonic, accountIndex, addressIndex, authorizations, upToLimit, dryRun, rollupAddress, log, debugLogger }: Omit<RollupCommandArgs, 'withdrawerAddress' | 'mnemonic' | 'privateKey'> & SignerAccountArgs & LoggerArgs & {
45
87
  authorizations: AttesterExitAuthorization[];
46
88
  upToLimit: boolean;
47
- }): Promise<import("viem").TransactionReceipt>;
89
+ dryRun?: boolean;
90
+ }): Promise<import("viem").TransactionReceipt | undefined>;
48
91
  /** Initiates an attester exit without changing the registered withdrawer's control over the payout. */
49
- export declare function initiateWithdrawByAttester({ rpcUrls, chainId, privateKey, mnemonic, attesterAddress, rollupAddress, log, debugLogger }: Omit<RollupCommandArgs, 'withdrawerAddress'> & LoggerArgs & {
92
+ export declare function initiateWithdrawByAttester({ rpcUrls, chainId, privateKey, mnemonic, accountIndex, addressIndex, attesterAddress, rollupAddress, log, debugLogger }: Omit<RollupCommandArgs, 'withdrawerAddress' | 'mnemonic' | 'privateKey'> & SignerAccountArgs & LoggerArgs & {
50
93
  attesterAddress: EthAddress;
51
94
  }): Promise<import("viem").TransactionReceipt>;
52
95
  export declare function pruneRollup({ rpcUrls, chainId, privateKey, mnemonic, rollupAddress, log, debugLogger }: RollupCommandArgs & LoggerArgs): Promise<void>;
@@ -54,4 +97,4 @@ export declare function fastForwardEpochs({ rpcUrls, chainId, rollupAddress, num
54
97
  numEpochs: bigint;
55
98
  }): Promise<void>;
56
99
  export declare function debugRollup({ rpcUrls, chainId, rollupAddress, log }: RollupCommandArgs & LoggerArgs): Promise<void>;
57
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBkYXRlX2wxX3ZhbGlkYXRvcnMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbWRzL2wxL3VwZGF0ZV9sMV92YWxpZGF0b3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUtBLE9BQU8sRUFBRSxLQUFLLHlCQUF5QixFQUErQixNQUFNLGdDQUFnQyxDQUFDO0FBRzdHLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUVoRSxPQUFPLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFPaEUsTUFBTSxXQUFXLGlCQUFpQjtJQUNoQyxPQUFPLEVBQUUsTUFBTSxFQUFFLENBQUM7SUFDbEIsT0FBTyxFQUFFLE1BQU0sQ0FBQztJQUNoQixVQUFVLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDcEIsUUFBUSxDQUFDLEVBQUUsTUFBTSxDQUFDO0lBQ2xCLGFBQWEsRUFBRSxVQUFVLENBQUM7SUFDMUIsaUJBQWlCLENBQUMsRUFBRSxVQUFVLENBQUM7Q0FDaEM7QUFFRCxNQUFNLFdBQVcsOEJBQThCO0lBQzdDLE9BQU8sRUFBRSxNQUFNLEVBQUUsQ0FBQztJQUNsQixPQUFPLEVBQUUsTUFBTSxDQUFDO0lBQ2hCLFVBQVUsQ0FBQyxFQUFFLE1BQU0sQ0FBQztJQUNwQixRQUFRLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDbEIsMEJBQTBCLEVBQUUsVUFBVSxDQUFDO0NBQ3hDO0FBRUQsTUFBTSxXQUFXLFVBQVU7SUFDekIsR0FBRyxFQUFFLEtBQUssQ0FBQztJQUNYLFdBQVcsRUFBRSxNQUFNLENBQUM7Q0FDckI7QUFFRCx3QkFBZ0IsaUJBQWlCOzs7RUFPaEM7QUFFRCx3QkFBc0IsY0FBYyxDQUFDLEVBQ25DLE9BQU8sRUFDUCxPQUFPLEVBQ1AsVUFBVSxFQUNWLFFBQVEsRUFDUixlQUFlLEVBQ2YsaUJBQWlCLEVBQ2pCLDBCQUEwQixFQUMxQixXQUFXLEVBQ1gsWUFB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
100
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBkYXRlX2wxX3ZhbGlkYXRvcnMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbWRzL2wxL3VwZGF0ZV9sMV92YWxpZGF0b3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUtBLE9BQU8sRUFDTCxLQUFLLHlCQUF5QixFQUkvQixNQUFNLGdDQUFnQyxDQUFDO0FBSXhDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUVoRSxPQUFPLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFZaEUsTUFBTSxXQUFXLGlCQUFpQjtJQUNoQyxPQUFPLEVBQUUsTUFBTSxFQUFFLENBQUM7SUFDbEIsT0FBTyxFQUFFLE1BQU0sQ0FBQztJQUNoQixVQUFVLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDcEIsUUFBUSxDQUFDLEVBQUUsTUFBTSxDQUFDO0lBQ2xCLGFBQWEsRUFBRSxVQUFVLENBQUM7SUFDMUIsaUJBQWlCLENBQUMsRUFBRSxVQUFVLENBQUM7Q0FDaEM7QUFFRCxzRUFBc0U7QUFDdEUsTUFBTSxNQUFNLGlCQUFpQixHQUFHO0lBQzlCLFVBQVUsQ0FBQyxFQUFFLE1BQU0sQ0FBQztJQUNwQixRQUFRLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDbEIsWUFBWSxDQUFDLEVBQUUsTUFBTSxDQUFDO0lBQ3RCLFlBQVksQ0FBQyxFQUFFLE1BQU0sQ0FBQztDQUN2QixDQUFDO0FBRUYsTUFBTSxXQUFXLDhCQUE4QjtJQUM3QyxPQUFPLEVBQUUsTUFBTSxFQUFFLENBQUM7SUFDbEIsT0FBTyxFQUFFLE1BQU0sQ0FBQztJQUNoQixVQUFVLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDcEIsUUFBUSxDQUFDLEVBQUUsTUFBTSxDQUFDO0lBQ2xCLDBCQUEwQixFQUFFLFVBQVUsQ0FBQztDQUN4QztBQUVELE1BQU0sV0FBVyxVQUFVO0lBQ3pCLEdBQUcsRUFBRSxLQUFLLENBQUM7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
@@ -1 +1 @@
1
- {"version":3,"file":"update_l1_validators.d.ts","sourceRoot":"","sources":["../../../src/cmds/l1/update_l1_validators.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"update_l1_validators.d.ts","sourceRoot":"","sources":["../../../src/cmds/l1/update_l1_validators.ts"],"names":[],"mappings":"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"}
@@ -1,17 +1,22 @@
1
1
  import { RollupAbi, StakingAssetHandlerAbi, TestERC20Abi } from '@aztec-foundation/l1-artifacts';
2
2
  import { createEthereumChain, isAnvilTestChain } from '@aztec-labs/ethereum/chain';
3
- import { createExtendedL1Client, getPublicClient } from '@aztec-labs/ethereum/client';
3
+ import { createExtendedL1Client, getPublicClient, makeL1HttpTransport } from '@aztec-labs/ethereum/client';
4
4
  import { getL1ContractsConfigEnvVars } from '@aztec-labs/ethereum/config';
5
- import { GSEContract, RollupContract } from '@aztec-labs/ethereum/contracts';
5
+ import { GSEContract, RegistryContract, RollupContract } from '@aztec-labs/ethereum/contracts';
6
6
  import { createL1TxUtils } from '@aztec-labs/ethereum/l1-tx-utils';
7
7
  import { EthCheatCodes } from '@aztec-labs/ethereum/test';
8
+ import { getActiveNetworkName } from '@aztec-labs/foundation/config';
8
9
  import { EthAddress } from '@aztec-labs/foundation/eth-address';
9
10
  import { Signature } from '@aztec-labs/foundation/eth-signature';
10
11
  import { DateProvider } from '@aztec-labs/foundation/timer';
11
12
  import { ZkPassportProofParams } from '@aztec-labs/stdlib/zkpassport';
12
- import { readFile } from 'node:fs/promises';
13
- import { encodeFunctionData, formatEther, getContract, isHex, maxUint256 } from 'viem';
13
+ import { readFile, writeFile } from 'node:fs/promises';
14
+ import { join } from 'node:path';
15
+ import { createPublicClient, encodeFunctionData, formatEther, getContract, isHex, maxUint256 } from 'viem';
14
16
  import { generatePrivateKey, mnemonicToAccount, privateKeyToAccount } from 'viem/accounts';
17
+ import { getNetworkConfig } from '../../config/network_config.js';
18
+ import { atomicUpdateFile } from '../../utils/commands.js';
19
+ import { deriveEthAttester } from '../validator_keys/shared.js';
15
20
  export function generateL1Account() {
16
21
  const privateKey = generatePrivateKey();
17
22
  const account = privateKeyToAccount(privateKey);
@@ -191,13 +196,131 @@ export async function removeL1Validator({ rpcUrls, chainId, privateKey, mnemonic
191
196
  });
192
197
  dualLog(`Transaction hash: ${receipt.transactionHash}`);
193
198
  }
199
+ /** Loads the published config of the network selected with --network, which takes precedence over the environment. */ export async function getAttesterExitNetwork(name) {
200
+ const networkName = getActiveNetworkName(name);
201
+ const cacheDir = process.env.DATA_DIRECTORY ? join(process.env.DATA_DIRECTORY, 'cache') : undefined;
202
+ const config = networkName === 'local' ? undefined : await getNetworkConfig(networkName, cacheDir);
203
+ if (networkName !== 'local' && !config) {
204
+ throw new Error(`Network ${networkName} has no published config`);
205
+ }
206
+ return {
207
+ name: networkName,
208
+ l1ChainId: config?.l1ChainId,
209
+ registryAddress: config ? EthAddress.fromString(config.registryAddress) : undefined
210
+ };
211
+ }
212
+ /**
213
+ * Resolves the chain ID and rollup an attester exit is signed for, without falling back to the Anvil chain ID.
214
+ * Whenever an RPC is given, its chain ID must match. Without one, signing is offline and needs the chain ID from a flag
215
+ * or --network; an L1_CHAIN_ID left in the environment alone is rejected because nothing confirms it.
216
+ */ export async function resolveAttesterExitTarget({ chainId, chainIdFromEnv = false, rpcUrls, network, rollupAddress, log }) {
217
+ if (!rollupAddress && !network) {
218
+ throw new Error('Provide --rollup, or --network to use the canonical rollup from the network registry');
219
+ }
220
+ if (!rollupAddress && !network?.registryAddress) {
221
+ throw new Error(`Network ${network?.name} publishes no registry address; provide --rollup`);
222
+ }
223
+ if (chainId !== undefined) {
224
+ assertValidChainId(chainId);
225
+ if (network?.l1ChainId !== undefined && chainId !== network.l1ChainId) {
226
+ throw new Error(`Chain ID ${chainId} does not match ${network.name}, which uses chain ID ${network.l1ChainId}`);
227
+ }
228
+ }
229
+ const expectedChainId = chainId ?? network?.l1ChainId;
230
+ if (!rpcUrls) {
231
+ if (expectedChainId === undefined) {
232
+ throw new Error('Provide --l1-chain-id, --network, or --l1-rpc-urls to select the chain to sign for');
233
+ }
234
+ if (!rollupAddress) {
235
+ throw new Error('Looking up the rollup in the network registry requires --l1-rpc-urls');
236
+ }
237
+ if (chainIdFromEnv && network?.l1ChainId === undefined) {
238
+ throw new Error(`Chain ID ${expectedChainId} comes only from L1_CHAIN_ID; confirm it with --l1-chain-id, --network, or --l1-rpc-urls`);
239
+ }
240
+ return {
241
+ chainId: expectedChainId,
242
+ rollupAddress
243
+ };
244
+ }
245
+ const rpcChainId = await getL1RpcChainId(rpcUrls, expectedChainId);
246
+ if (rollupAddress) {
247
+ return {
248
+ chainId: rpcChainId,
249
+ rollupAddress
250
+ };
251
+ }
252
+ const registryAddress = network.registryAddress;
253
+ const client = getPublicClient({
254
+ l1RpcUrls: rpcUrls,
255
+ l1ChainId: rpcChainId
256
+ });
257
+ const canonicalRollup = await new RegistryContract(client, registryAddress).getCanonicalAddress();
258
+ log(`Using canonical rollup ${canonicalRollup} from the ${network.name} registry ${registryAddress}`);
259
+ return {
260
+ chainId: rpcChainId,
261
+ rollupAddress: canonicalRollup
262
+ };
263
+ }
264
+ /** Returns the chain ID the L1 RPC reports, failing if it differs from `expectedChainId`. */ async function getL1RpcChainId(rpcUrls, expectedChainId) {
265
+ const rpcChainId = await createPublicClient({
266
+ transport: makeL1HttpTransport(rpcUrls)
267
+ }).getChainId();
268
+ if (expectedChainId !== undefined && rpcChainId !== expectedChainId) {
269
+ throw new Error(`The L1 RPC reports chain ID ${rpcChainId}, but chain ID ${expectedChainId} was requested`);
270
+ }
271
+ return rpcChainId;
272
+ }
273
+ /** Signs an exit authorization locally and writes a JSON array accepted by the batch command. */ export async function signAttesterExit({ rpcUrls, chainId, privateKey, mnemonic, accountIndex, addressIndex, rollupAddress, attesterAddress, deadline, output, append = false, log }) {
274
+ assertValidChainId(chainId);
275
+ const account = getSignerAccount({
276
+ privateKey,
277
+ mnemonic,
278
+ accountIndex,
279
+ addressIndex
280
+ });
281
+ if (account.address.toLowerCase() !== attesterAddress.toString().toLowerCase()) {
282
+ throw new Error('The signing account must match the attester address');
283
+ }
284
+ const chain = createEthereumChain(rpcUrls, chainId);
285
+ const client = createExtendedL1Client(rpcUrls, account, chain.chainInfo);
286
+ const rollup = new RollupContract(client, rollupAddress);
287
+ const authorization = await rollup.createAttesterExitAuthorization(attesterAddress, deadline, (typedData)=>account.signTypedData(typedData));
288
+ const existingAuthorizations = append ? await readAttesterExitAuthorizationJson(output).catch((error)=>{
289
+ if (!isRecord(error) || error.code !== 'ENOENT') {
290
+ throw error;
291
+ }
292
+ return undefined;
293
+ }) : undefined;
294
+ const authorizations = existingAuthorizations ?? [];
295
+ authorizations.push({
296
+ attester: authorization.attester.toString(),
297
+ deadline: authorization.deadline.toString(),
298
+ signature: Signature.fromViemSignature(authorization.signature).toString()
299
+ });
300
+ const json = JSON.stringify(authorizations, null, 2);
301
+ if (existingAuthorizations) {
302
+ await atomicUpdateFile(output, `${json}\n`);
303
+ } else {
304
+ await writeFile(output, `${json}\n`, {
305
+ flag: 'wx'
306
+ });
307
+ }
308
+ log(`Wrote attester exit authorization to ${output}`);
309
+ }
194
310
  /** Reads relayed attester exit authorizations from a JSON array. */ export async function readAttesterExitAuthorizations(path) {
195
- const parsed = JSON.parse(await readFile(path, 'utf-8'));
196
- if (!Array.isArray(parsed) || parsed.length === 0) {
311
+ const parsed = await readAttesterExitAuthorizationJson(path);
312
+ if (parsed.length === 0) {
197
313
  throw new Error('Attester exit authorization file must contain a non-empty JSON array');
198
314
  }
199
315
  return parsed.map((value, index)=>parseAttesterExitAuthorization(value, index));
200
316
  }
317
+ async function readAttesterExitAuthorizationJson(path) {
318
+ const parsed = JSON.parse(await readFile(path, 'utf-8'));
319
+ if (!Array.isArray(parsed)) {
320
+ throw new Error('Attester exit authorization file must contain a JSON array');
321
+ }
322
+ return parsed;
323
+ }
201
324
  function isRecord(value) {
202
325
  return typeof value === 'object' && value !== null && !Array.isArray(value);
203
326
  }
@@ -212,7 +335,7 @@ function parseAttesterExitAuthorization(value, index) {
212
335
  if (typeof authorization.deadline !== 'string' || !/^\d+$/.test(authorization.deadline)) {
213
336
  throw new Error(`Attester exit authorization ${index} deadline must be a decimal string`);
214
337
  }
215
- if (typeof authorization.signature !== 'string' || !isHex(authorization.signature)) {
338
+ if (typeof authorization.signature !== 'string' || !isHex(authorization.signature) || !Signature.isValidString(authorization.signature)) {
216
339
  throw new Error(`Attester exit authorization ${index} has an invalid signature`);
217
340
  }
218
341
  return {
@@ -221,32 +344,73 @@ function parseAttesterExitAuthorization(value, index) {
221
344
  signature: Signature.fromString(authorization.signature).toViemSignature()
222
345
  };
223
346
  }
224
- /** Relays a batch of attester-signed exits. */ export async function initiateWithdrawByAttesterBatch({ rpcUrls, chainId, privateKey, mnemonic, authorizations, upToLimit, rollupAddress, log, debugLogger }) {
225
- const account = getAccount(privateKey, mnemonic);
226
- const chain = createEthereumChain(rpcUrls, chainId);
227
- const client = createExtendedL1Client(rpcUrls, account, chain.chainInfo);
347
+ /**
348
+ * Confirms the RPC is on the requested chain, then checks each imported signature so a bad entry is named rather than
349
+ * reverting the whole batch. Duplicates and deadlines are left to the chain, which with --up-to-limit never looks past
350
+ * the processed prefix.
351
+ */ async function checkAttesterExitBatch(rollup, authorizations, rpcUrls, chainId) {
352
+ await getL1RpcChainId(rpcUrls, chainId);
353
+ for (const [index, authorization] of authorizations.entries()){
354
+ await rollup.validateAttesterExitSignature(authorization, index);
355
+ }
356
+ }
357
+ /** Relays a batch of attester-signed exits. */ export async function initiateWithdrawByAttesterBatch({ rpcUrls, chainId, privateKey, mnemonic, accountIndex, addressIndex, authorizations, upToLimit, dryRun = false, rollupAddress, log, debugLogger }) {
358
+ if (dryRun) {
359
+ assertValidChainId(chainId);
360
+ // A dry run needs no key, but check any signer options given so the same command can later run without --dry-run.
361
+ if (privateKey || mnemonic || accountIndex !== undefined || addressIndex !== undefined) {
362
+ getSignerAccount({
363
+ privateKey,
364
+ mnemonic,
365
+ accountIndex,
366
+ addressIndex
367
+ });
368
+ }
369
+ const client = getPublicClient({
370
+ l1RpcUrls: rpcUrls,
371
+ l1ChainId: chainId
372
+ });
373
+ const rollup = new RollupContract(client, rollupAddress);
374
+ await checkAttesterExitBatch(rollup, authorizations, rpcUrls, chainId);
375
+ const processedCount = await rollup.simulateAttesterExitBatch(authorizations, upToLimit);
376
+ log(`Dry run: would process ${processedCount} of ${authorizations.length} attester exit authorizations at current chain state.`);
377
+ logRemainingAttesterExits(log, processedCount, authorizations.length);
378
+ return;
379
+ }
380
+ const account = getSignerAccount({
381
+ privateKey,
382
+ mnemonic,
383
+ accountIndex,
384
+ addressIndex
385
+ });
386
+ const client = createExtendedL1Client(rpcUrls, account, createEthereumChain(rpcUrls, chainId).chainInfo);
228
387
  const rollup = new RollupContract(client, rollupAddress);
388
+ await checkAttesterExitBatch(rollup, authorizations, rpcUrls, chainId);
229
389
  const l1TxUtils = createL1TxUtils(client, {
230
390
  logger: debugLogger
231
391
  });
232
- const { receipt } = upToLimit ? await rollup.initiateWithdrawByAttesterBatchUpToLimit(l1TxUtils, authorizations) : await rollup.initiateWithdrawByAttesterBatch(l1TxUtils, authorizations);
233
- if (receipt.status !== 'success') {
234
- throw new Error(`Attester exit batch reverted: ${receipt.transactionHash}`);
235
- }
236
- log(`Submitted ${authorizations.length} attester exit authorizations. Transaction hash: ${receipt.transactionHash}`);
237
- if (upToLimit) {
238
- log('The rollup processed the largest permitted prefix of the authorization list.');
239
- }
240
- debugLogger.info('Attester exit batch submitted', {
392
+ const { receipt, processedCount, remainingCount } = await rollup.submitAttesterExitBatch(l1TxUtils, authorizations, upToLimit);
393
+ log(`Processed ${processedCount} of ${authorizations.length} attester exit authorizations. Transaction hash: ${receipt.transactionHash}`);
394
+ logRemainingAttesterExits(log, processedCount, authorizations.length);
395
+ debugLogger.info('Attester exit batch processed', {
241
396
  authorizationCount: authorizations.length,
397
+ processedCount,
398
+ remainingCount,
399
+ remainingStartIndex: remainingCount > 0 ? processedCount : undefined,
400
+ remainingEndIndexExclusive: remainingCount > 0 ? authorizations.length : undefined,
242
401
  upToLimit,
243
402
  rollup: rollupAddress.toString(),
244
403
  transactionHash: receipt.transactionHash
245
404
  });
246
405
  return receipt;
247
406
  }
248
- /** Initiates an attester exit without changing the registered withdrawer's control over the payout. */ export async function initiateWithdrawByAttester({ rpcUrls, chainId, privateKey, mnemonic, attesterAddress, rollupAddress, log, debugLogger }) {
249
- const account = getAccount(privateKey, mnemonic);
407
+ /** Initiates an attester exit without changing the registered withdrawer's control over the payout. */ export async function initiateWithdrawByAttester({ rpcUrls, chainId, privateKey, mnemonic, accountIndex, addressIndex, attesterAddress, rollupAddress, log, debugLogger }) {
408
+ const account = getSignerAccount({
409
+ privateKey,
410
+ mnemonic,
411
+ accountIndex,
412
+ addressIndex
413
+ });
250
414
  if (account.address.toLowerCase() !== attesterAddress.toString().toLowerCase()) {
251
415
  throw new Error('The transaction signer must match the attester address');
252
416
  }
@@ -346,12 +510,42 @@ export async function debugRollup({ rpcUrls, chainId, rollupAddress, log }) {
346
510
  const proposer = await rollup.getProposerAt(nextBlockTS);
347
511
  log(`Proposer NOW: ${proposer.toString()}`);
348
512
  }
513
+ function logRemainingAttesterExits(log, processedCount, authorizationCount) {
514
+ const remainingCount = authorizationCount - processedCount;
515
+ log(remainingCount > 0 ? `Remaining authorizations: ${remainingCount}. Zero-based JSON array indices ${processedCount} through ${authorizationCount - 1} (inclusive).` : 'Remaining authorizations: 0 (none).');
516
+ }
349
517
  function makeDualLog(log, debugLogger) {
350
518
  return (msg)=>{
351
519
  log(msg);
352
520
  debugLogger.info(msg);
353
521
  };
354
522
  }
523
+ /** `createEthereumChain` maps a falsy chain ID to Anvil, so reject it before a chain is built from it. */ function assertValidChainId(chainId) {
524
+ if (!Number.isSafeInteger(chainId) || chainId <= 0) {
525
+ throw new Error('Chain ID must be a positive safe integer');
526
+ }
527
+ }
528
+ function getSignerAccount({ privateKey, mnemonic, accountIndex, addressIndex }) {
529
+ if (Boolean(privateKey) === Boolean(mnemonic)) {
530
+ throw new Error('Provide either a private key or a mnemonic for the signer');
531
+ }
532
+ if (privateKey) {
533
+ if (accountIndex !== undefined || addressIndex !== undefined) {
534
+ throw new Error('Account and address indices require a mnemonic');
535
+ }
536
+ return getAccount(privateKey, undefined);
537
+ }
538
+ const selectedAccountIndex = accountIndex ?? 0;
539
+ const selectedAddressIndex = addressIndex ?? 0;
540
+ if (!Number.isSafeInteger(selectedAccountIndex) || selectedAccountIndex < 0 || !Number.isSafeInteger(selectedAddressIndex) || selectedAddressIndex < 0) {
541
+ throw new Error('Account and address indices must be non-negative safe integers');
542
+ }
543
+ const derivedKey = deriveEthAttester(mnemonic, selectedAccountIndex, selectedAddressIndex);
544
+ if (typeof derivedKey !== 'string') {
545
+ throw new Error('Expected a local signer private key');
546
+ }
547
+ return privateKeyToAccount(derivedKey);
548
+ }
355
549
  function getAccount(privateKey, mnemonic) {
356
550
  if (!privateKey && !mnemonic) {
357
551
  throw new Error('Either privateKey or mnemonic must be provided to create a wallet client');