@aztec/cli 0.0.1-commit.b655e406 → 0.0.1-commit.b8a057fa

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 (191) hide show
  1. package/README.md +1 -1
  2. package/dest/cmds/aztec_node/block_number.d.ts +1 -1
  3. package/dest/cmds/aztec_node/block_number.js +1 -1
  4. package/dest/cmds/aztec_node/get_block.d.ts +1 -1
  5. package/dest/cmds/aztec_node/get_block.d.ts.map +1 -1
  6. package/dest/cmds/aztec_node/get_block.js +2 -1
  7. package/dest/cmds/aztec_node/get_current_min_fee.d.ts +3 -0
  8. package/dest/cmds/aztec_node/get_current_min_fee.d.ts.map +1 -0
  9. package/dest/cmds/aztec_node/{get_current_base_fee.js → get_current_min_fee.js} +2 -2
  10. package/dest/cmds/aztec_node/get_l1_to_l2_message_witness.d.ts +1 -1
  11. package/dest/cmds/aztec_node/get_logs.d.ts +30 -3
  12. package/dest/cmds/aztec_node/get_logs.d.ts.map +1 -1
  13. package/dest/cmds/aztec_node/get_logs.js +39 -29
  14. package/dest/cmds/aztec_node/get_node_info.d.ts +1 -1
  15. package/dest/cmds/aztec_node/get_node_info.d.ts.map +1 -1
  16. package/dest/cmds/aztec_node/get_node_info.js +0 -2
  17. package/dest/cmds/aztec_node/index.d.ts +1 -1
  18. package/dest/cmds/aztec_node/index.d.ts.map +1 -1
  19. package/dest/cmds/aztec_node/index.js +16 -6
  20. package/dest/cmds/contracts/index.d.ts +1 -1
  21. package/dest/cmds/contracts/inspect_contract.d.ts +1 -1
  22. package/dest/cmds/contracts/inspect_contract.d.ts.map +1 -1
  23. package/dest/cmds/contracts/inspect_contract.js +4 -10
  24. package/dest/cmds/contracts/parse_parameter_struct.d.ts +1 -1
  25. package/dest/cmds/infrastructure/index.d.ts +1 -1
  26. package/dest/cmds/infrastructure/index.d.ts.map +1 -1
  27. package/dest/cmds/infrastructure/index.js +0 -1
  28. package/dest/cmds/infrastructure/sequencers.d.ts +1 -2
  29. package/dest/cmds/infrastructure/sequencers.d.ts.map +1 -1
  30. package/dest/cmds/infrastructure/sequencers.js +11 -4
  31. package/dest/cmds/infrastructure/setup_l2_contract.d.ts +1 -1
  32. package/dest/cmds/infrastructure/setup_l2_contract.d.ts.map +1 -1
  33. package/dest/cmds/infrastructure/setup_l2_contract.js +12 -7
  34. package/dest/cmds/l1/advance_epoch.d.ts +1 -1
  35. package/dest/cmds/l1/assume_proven_through.d.ts +3 -2
  36. package/dest/cmds/l1/assume_proven_through.d.ts.map +1 -1
  37. package/dest/cmds/l1/assume_proven_through.js +3 -4
  38. package/dest/cmds/l1/bridge_erc20.d.ts +1 -1
  39. package/dest/cmds/l1/bridge_erc20.d.ts.map +1 -1
  40. package/dest/cmds/l1/bridge_erc20.js +2 -1
  41. package/dest/cmds/l1/compute_genesis_values.d.ts +4 -0
  42. package/dest/cmds/l1/compute_genesis_values.d.ts.map +1 -0
  43. package/dest/cmds/l1/compute_genesis_values.js +17 -0
  44. package/dest/cmds/l1/create_l1_account.d.ts +1 -1
  45. package/dest/cmds/l1/deploy_l1_contracts_cmd.d.ts +4 -0
  46. package/dest/cmds/l1/deploy_l1_contracts_cmd.d.ts.map +1 -0
  47. package/dest/cmds/l1/{deploy_l1_contracts.js → deploy_l1_contracts_cmd.js} +39 -5
  48. package/dest/cmds/l1/deploy_new_rollup.d.ts +4 -4
  49. package/dest/cmds/l1/deploy_new_rollup.d.ts.map +1 -1
  50. package/dest/cmds/l1/deploy_new_rollup.js +4 -6
  51. package/dest/cmds/l1/get_l1_addresses.d.ts +1 -1
  52. package/dest/cmds/l1/get_l1_addresses.d.ts.map +1 -1
  53. package/dest/cmds/l1/get_l1_addresses.js +5 -2
  54. package/dest/cmds/l1/get_l1_balance.d.ts +1 -1
  55. package/dest/cmds/l1/get_l1_balance.js +4 -2
  56. package/dest/cmds/l1/governance_utils.d.ts +5 -5
  57. package/dest/cmds/l1/governance_utils.d.ts.map +1 -1
  58. package/dest/cmds/l1/governance_utils.js +3 -1
  59. package/dest/cmds/l1/index.d.ts +1 -2
  60. package/dest/cmds/l1/index.d.ts.map +1 -1
  61. package/dest/cmds/l1/index.js +17 -10
  62. package/dest/cmds/l1/prover_stats.d.ts +1 -1
  63. package/dest/cmds/l1/prover_stats.d.ts.map +1 -1
  64. package/dest/cmds/l1/prover_stats.js +32 -30
  65. package/dest/cmds/l1/trigger_seed_snapshot.d.ts +2 -2
  66. package/dest/cmds/l1/trigger_seed_snapshot.d.ts.map +1 -1
  67. package/dest/cmds/l1/trigger_seed_snapshot.js +2 -1
  68. package/dest/cmds/l1/update_l1_validators.d.ts +7 -7
  69. package/dest/cmds/l1/update_l1_validators.d.ts.map +1 -1
  70. package/dest/cmds/l1/update_l1_validators.js +58 -20
  71. package/dest/cmds/misc/compute_selector.d.ts +1 -1
  72. package/dest/cmds/misc/example_contracts.d.ts +1 -1
  73. package/dest/cmds/misc/generate_bootnode_enr.d.ts +1 -1
  74. package/dest/cmds/misc/generate_p2p_private_key.d.ts +1 -1
  75. package/dest/cmds/misc/generate_secret_and_hash.d.ts +1 -1
  76. package/dest/cmds/misc/generate_secret_and_hash.js +1 -1
  77. package/dest/cmds/misc/generate_secret_key.d.ts +1 -1
  78. package/dest/cmds/misc/get_canonical_sponsored_fpc_address.d.ts +1 -1
  79. package/dest/cmds/misc/index.d.ts +1 -1
  80. package/dest/cmds/misc/index.d.ts.map +1 -1
  81. package/dest/cmds/misc/index.js +1 -1
  82. package/dest/cmds/misc/update/common.d.ts +1 -1
  83. package/dest/cmds/misc/update/github.d.ts +1 -1
  84. package/dest/cmds/misc/update/noir.d.ts +1 -1
  85. package/dest/cmds/misc/update/npm.d.ts +1 -1
  86. package/dest/cmds/misc/update/npm.js +1 -1
  87. package/dest/cmds/misc/update/utils.d.ts +1 -1
  88. package/dest/cmds/misc/update.d.ts +1 -1
  89. package/dest/cmds/validator_keys/add.d.ts +1 -1
  90. package/dest/cmds/validator_keys/add.d.ts.map +1 -1
  91. package/dest/cmds/validator_keys/add.js +20 -7
  92. package/dest/cmds/validator_keys/eth_json_v3_worker.d.ts +2 -0
  93. package/dest/cmds/validator_keys/eth_json_v3_worker.d.ts.map +1 -0
  94. package/dest/cmds/validator_keys/eth_json_v3_worker.js +27 -0
  95. package/dest/cmds/validator_keys/generate_bls_keypair.d.ts +1 -1
  96. package/dest/cmds/validator_keys/generate_bls_keypair.d.ts.map +1 -1
  97. package/dest/cmds/validator_keys/generate_bls_keypair.js +3 -2
  98. package/dest/cmds/validator_keys/index.d.ts +1 -1
  99. package/dest/cmds/validator_keys/index.d.ts.map +1 -1
  100. package/dest/cmds/validator_keys/index.js +17 -4
  101. package/dest/cmds/validator_keys/new.d.ts +12 -4
  102. package/dest/cmds/validator_keys/new.d.ts.map +1 -1
  103. package/dest/cmds/validator_keys/new.js +163 -19
  104. package/dest/cmds/validator_keys/shared.d.ts +4 -4
  105. package/dest/cmds/validator_keys/shared.d.ts.map +1 -1
  106. package/dest/cmds/validator_keys/shared.js +97 -51
  107. package/dest/cmds/validator_keys/staker.d.ts +38 -0
  108. package/dest/cmds/validator_keys/staker.d.ts.map +1 -0
  109. package/dest/cmds/validator_keys/staker.js +210 -0
  110. package/dest/cmds/validator_keys/utils.d.ts +25 -0
  111. package/dest/cmds/validator_keys/utils.d.ts.map +1 -0
  112. package/dest/cmds/validator_keys/utils.js +52 -0
  113. package/dest/config/cached_fetch.d.ts +19 -10
  114. package/dest/config/cached_fetch.d.ts.map +1 -1
  115. package/dest/config/cached_fetch.js +110 -32
  116. package/dest/config/chain_l2_config.d.ts +18 -38
  117. package/dest/config/chain_l2_config.d.ts.map +1 -1
  118. package/dest/config/chain_l2_config.js +48 -463
  119. package/dest/config/enrich_env.d.ts +1 -1
  120. package/dest/config/generated/networks.d.ts +239 -0
  121. package/dest/config/generated/networks.d.ts.map +1 -0
  122. package/dest/config/generated/networks.js +240 -0
  123. package/dest/config/get_l1_config.d.ts +3 -2
  124. package/dest/config/get_l1_config.d.ts.map +1 -1
  125. package/dest/config/get_l1_config.js +3 -1
  126. package/dest/config/index.d.ts +1 -1
  127. package/dest/config/network_config.d.ts +7 -4
  128. package/dest/config/network_config.d.ts.map +1 -1
  129. package/dest/config/network_config.js +70 -30
  130. package/dest/utils/aztec.d.ts +7 -14
  131. package/dest/utils/aztec.d.ts.map +1 -1
  132. package/dest/utils/aztec.js +19 -41
  133. package/dest/utils/commands.d.ts +20 -11
  134. package/dest/utils/commands.d.ts.map +1 -1
  135. package/dest/utils/commands.js +26 -15
  136. package/dest/utils/encoding.d.ts +1 -1
  137. package/dest/utils/encoding.js +1 -1
  138. package/dest/utils/github.d.ts +1 -1
  139. package/dest/utils/index.d.ts +1 -1
  140. package/dest/utils/inspect.d.ts +3 -2
  141. package/dest/utils/inspect.d.ts.map +1 -1
  142. package/dest/utils/inspect.js +15 -12
  143. package/dest/utils/setup_contracts.d.ts +1 -1
  144. package/package.json +44 -31
  145. package/public_include_metric_prefixes.json +1 -0
  146. package/src/cmds/aztec_node/block_number.ts +1 -1
  147. package/src/cmds/aztec_node/get_block.ts +2 -1
  148. package/src/cmds/aztec_node/{get_current_base_fee.ts → get_current_min_fee.ts} +2 -2
  149. package/src/cmds/aztec_node/get_logs.ts +70 -37
  150. package/src/cmds/aztec_node/get_node_info.ts +0 -2
  151. package/src/cmds/aztec_node/index.ts +16 -11
  152. package/src/cmds/contracts/inspect_contract.ts +4 -11
  153. package/src/cmds/infrastructure/index.ts +0 -1
  154. package/src/cmds/infrastructure/sequencers.ts +7 -5
  155. package/src/cmds/infrastructure/setup_l2_contract.ts +12 -7
  156. package/src/cmds/l1/assume_proven_through.ts +4 -4
  157. package/src/cmds/l1/bridge_erc20.ts +2 -1
  158. package/src/cmds/l1/compute_genesis_values.ts +29 -0
  159. package/src/cmds/l1/{deploy_l1_contracts.ts → deploy_l1_contracts_cmd.ts} +39 -23
  160. package/src/cmds/l1/deploy_new_rollup.ts +5 -12
  161. package/src/cmds/l1/get_l1_addresses.ts +4 -2
  162. package/src/cmds/l1/get_l1_balance.ts +2 -2
  163. package/src/cmds/l1/governance_utils.ts +3 -8
  164. package/src/cmds/l1/index.ts +30 -21
  165. package/src/cmds/l1/prover_stats.ts +42 -31
  166. package/src/cmds/l1/trigger_seed_snapshot.ts +2 -1
  167. package/src/cmds/l1/update_l1_validators.ts +52 -32
  168. package/src/cmds/misc/generate_secret_and_hash.ts +1 -1
  169. package/src/cmds/misc/index.ts +1 -1
  170. package/src/cmds/misc/update/npm.ts +1 -1
  171. package/src/cmds/validator_keys/add.ts +20 -10
  172. package/src/cmds/validator_keys/eth_json_v3_worker.ts +30 -0
  173. package/src/cmds/validator_keys/generate_bls_keypair.ts +3 -2
  174. package/src/cmds/validator_keys/index.ts +85 -25
  175. package/src/cmds/validator_keys/new.ts +211 -25
  176. package/src/cmds/validator_keys/shared.ts +117 -60
  177. package/src/cmds/validator_keys/staker.ts +301 -0
  178. package/src/cmds/validator_keys/utils.ts +81 -0
  179. package/src/config/cached_fetch.ts +119 -31
  180. package/src/config/chain_l2_config.ts +47 -602
  181. package/src/config/generated/networks.ts +244 -0
  182. package/src/config/get_l1_config.ts +4 -1
  183. package/src/config/network_config.ts +80 -31
  184. package/src/utils/aztec.ts +30 -95
  185. package/src/utils/commands.ts +29 -15
  186. package/src/utils/encoding.ts +1 -1
  187. package/src/utils/inspect.ts +13 -10
  188. package/dest/cmds/aztec_node/get_current_base_fee.d.ts +0 -3
  189. package/dest/cmds/aztec_node/get_current_base_fee.d.ts.map +0 -1
  190. package/dest/cmds/l1/deploy_l1_contracts.d.ts +0 -4
  191. package/dest/cmds/l1/deploy_l1_contracts.d.ts.map +0 -1
@@ -1,39 +1,128 @@
1
+ import { prettyPrintJSON } from '@aztec/cli/utils';
2
+ import { createEthereumChain } from '@aztec/ethereum/chain';
3
+ import { GSEContract } from '@aztec/ethereum/contracts';
1
4
  import { wordlist } from '@scure/bip39/wordlists/english.js';
2
- import { dirname } from 'path';
5
+ import { readFile, writeFile } from 'fs/promises';
6
+ import { basename, dirname, join } from 'path';
7
+ import { createPublicClient, fallback, http } from 'viem';
3
8
  import { generateMnemonic, mnemonicToAccount } from 'viem/accounts';
4
9
  import { buildValidatorEntries, logValidatorSummaries, maybePrintJson, resolveKeystoreOutputPath, writeBlsBn254ToFile, writeEthJsonV3ToFile, writeKeystoreFile } from './shared.js';
5
- export async function newValidatorKeystore(options, log) {
6
- const { dataDir, file, count, publisherCount = 0, json, coinbase, accountIndex = 0, addressIndex = 0, feeRecipient, remoteSigner, fundingAccount, blsOnly, blsPath, ikm, mnemonic: _mnemonic, password, outDir } = options;
7
- if (remoteSigner && !_mnemonic) {
8
- throw new Error('Using --remote-signer requires a deterministic key source. Provide --mnemonic to derive keys, or omit --remote-signer to write new private keys to keystore.');
10
+ import { processAttesterAccounts } from './staker.js';
11
+ import { validateBlsPathOptions, validatePublisherOptions, validateRemoteSignerOptions, validateStakerOutputOptions } from './utils.js';
12
+ function validatePassword(password, source) {
13
+ if (password.length === 0) {
14
+ throw new Error(`${source} cannot be empty`);
15
+ }
16
+ return password;
17
+ }
18
+ function stripOneTrailingNewline(password) {
19
+ if (password.endsWith('\n')) {
20
+ password = password.slice(0, -1);
21
+ }
22
+ if (password.endsWith('\r')) {
23
+ password = password.slice(0, -1);
24
+ }
25
+ return password;
26
+ }
27
+ async function resolvePasswordSource(source) {
28
+ if (source.password !== undefined && source.passwordFile !== undefined) {
29
+ throw new Error(`${source.passwordOption} and ${source.passwordFileOption} cannot be used together`);
30
+ }
31
+ if (source.password !== undefined) {
32
+ return validatePassword(source.password, source.passwordOption);
9
33
  }
34
+ if (source.passwordFile !== undefined) {
35
+ if (source.passwordFile.length === 0) {
36
+ throw new Error(`${source.passwordFileOption} cannot be empty`);
37
+ }
38
+ const password = stripOneTrailingNewline(await readFile(source.passwordFile, 'utf-8'));
39
+ return validatePassword(password, source.passwordFileOption);
40
+ }
41
+ return undefined;
42
+ }
43
+ async function resolvePasswords(options) {
44
+ const sharedPassword = await resolvePasswordSource({
45
+ password: options.password,
46
+ passwordFile: options.passwordFile,
47
+ passwordOption: '--password',
48
+ passwordFileOption: '--password-file'
49
+ });
50
+ const ethPassword = await resolvePasswordSource({
51
+ password: options.ethPassword,
52
+ passwordFile: options.ethPasswordFile,
53
+ passwordOption: '--eth-password',
54
+ passwordFileOption: '--eth-password-file'
55
+ }) ?? sharedPassword;
56
+ const blsPassword = await resolvePasswordSource({
57
+ password: options.blsPassword,
58
+ passwordFile: options.blsPasswordFile,
59
+ passwordOption: '--bls-password',
60
+ passwordFileOption: '--bls-password-file'
61
+ }) ?? sharedPassword;
62
+ if (ethPassword === undefined && blsPassword === undefined) {
63
+ return {};
64
+ }
65
+ if (ethPassword === undefined || blsPassword === undefined) {
66
+ throw new Error('Both ETH and BLS passwords are required when writing encrypted keystores. Provide --password to use one password for both, or provide both --eth-password and --bls-password.');
67
+ }
68
+ return {
69
+ ethPassword,
70
+ blsPassword
71
+ };
72
+ }
73
+ export async function newValidatorKeystore(options, log) {
74
+ // validate bls-path inputs before proceeding with key generation
75
+ validateBlsPathOptions(options);
76
+ // validate staker output options before proceeding with key generation
77
+ validateStakerOutputOptions(options);
78
+ // validate publisher options
79
+ validatePublisherOptions(options);
80
+ // validate remote signer options
81
+ validateRemoteSignerOptions(options);
82
+ const { dataDir, file, count, publisherCount = 0, publishers, json, coinbase, accountIndex = 0, addressIndex = 0, feeRecipient, remoteSigner, blsPath, ikm, mnemonic: _mnemonic, password: passwordOption, passwordFile, ethPassword: ethPasswordOption, ethPasswordFile, blsPassword: blsPasswordOption, blsPasswordFile, encryptedKeystoreDir, stakerOutput, gseAddress, l1RpcUrls, l1ChainId } = options;
83
+ const { ethPassword, blsPassword } = await resolvePasswords({
84
+ password: passwordOption,
85
+ passwordFile,
86
+ ethPassword: ethPasswordOption,
87
+ ethPasswordFile,
88
+ blsPassword: blsPasswordOption,
89
+ blsPasswordFile
90
+ });
91
+ const shouldEncryptKeystores = ethPassword !== undefined && blsPassword !== undefined;
10
92
  const mnemonic = _mnemonic ?? generateMnemonic(wordlist);
93
+ if (!_mnemonic && !json && !shouldEncryptKeystores) {
94
+ log('No mnemonic provided, generating new one...');
95
+ log(`Using new mnemonic:`);
96
+ log('');
97
+ log(mnemonic);
98
+ log('');
99
+ }
11
100
  const validatorCount = typeof count === 'number' && Number.isFinite(count) && count > 0 ? Math.floor(count) : 1;
12
101
  const { outputPath } = await resolveKeystoreOutputPath(dataDir, file);
102
+ const keystoreOutDir = dirname(outputPath);
13
103
  const { validators, summaries } = await buildValidatorEntries({
14
104
  validatorCount,
15
105
  publisherCount,
106
+ publishers,
16
107
  accountIndex,
17
108
  baseAddressIndex: addressIndex,
18
109
  mnemonic,
19
110
  ikm,
20
111
  blsPath,
21
- blsOnly,
22
112
  feeRecipient,
23
113
  coinbase,
24
- remoteSigner,
25
- fundingAccount
114
+ remoteSigner
26
115
  });
27
116
  // If password provided, write ETH JSON V3 and BLS BN254 keystores and replace plaintext
28
- if (password !== undefined) {
29
- const keystoreOutDir = outDir && outDir.length > 0 ? outDir : dirname(outputPath);
117
+ if (shouldEncryptKeystores) {
118
+ const encryptedKeystoreOutDir = encryptedKeystoreDir && encryptedKeystoreDir.length > 0 ? encryptedKeystoreDir : keystoreOutDir;
30
119
  await writeEthJsonV3ToFile(validators, {
31
- outDir: keystoreOutDir,
32
- password
120
+ outDir: encryptedKeystoreOutDir,
121
+ password: ethPassword
33
122
  });
34
123
  await writeBlsBn254ToFile(validators, {
35
- outDir: keystoreOutDir,
36
- password
124
+ outDir: encryptedKeystoreOutDir,
125
+ password: blsPassword
37
126
  });
38
127
  }
39
128
  const keystore = {
@@ -41,13 +130,63 @@ export async function newValidatorKeystore(options, log) {
41
130
  validators
42
131
  };
43
132
  await writeKeystoreFile(outputPath, keystore);
44
- maybePrintJson(log, json, keystore);
45
- if (!json) {
133
+ // Generate staker outputs if requested
134
+ const allStakerOutputs = [];
135
+ if (stakerOutput && gseAddress && l1RpcUrls && l1ChainId !== undefined) {
136
+ const chain = createEthereumChain(l1RpcUrls, l1ChainId);
137
+ const publicClient = createPublicClient({
138
+ chain: chain.chainInfo,
139
+ transport: fallback(l1RpcUrls.map((url)=>http(url, {
140
+ batch: false
141
+ })))
142
+ });
143
+ const gse = new GSEContract(publicClient, gseAddress);
144
+ // Extract keystore base name without extension for unique staker output filenames
145
+ const keystoreBaseName = basename(outputPath, '.json');
146
+ // Process each validator
147
+ for(let i = 0; i < validators.length; i++){
148
+ const validator = validators[i];
149
+ const outputs = await processAttesterAccounts(validator.attester, gse);
150
+ // Collect all staker outputs
151
+ for(let j = 0; j < outputs.length; j++){
152
+ allStakerOutputs.push(outputs[j]);
153
+ }
154
+ }
155
+ // Write a single JSON file with all staker outputs
156
+ if (allStakerOutputs.length > 0) {
157
+ const stakerOutputPath = join(keystoreOutDir, `${keystoreBaseName}_staker_output.json`);
158
+ await writeFile(stakerOutputPath, prettyPrintJSON(allStakerOutputs), 'utf-8');
159
+ }
160
+ }
161
+ const outputData = !_mnemonic && !shouldEncryptKeystores ? {
162
+ ...keystore,
163
+ generatedMnemonic: mnemonic
164
+ } : keystore;
165
+ // Handle JSON output
166
+ if (json) {
167
+ if (stakerOutput && allStakerOutputs.length > 0) {
168
+ const combinedOutput = {
169
+ keystore: outputData,
170
+ staker: allStakerOutputs
171
+ };
172
+ maybePrintJson(log, json, combinedOutput);
173
+ } else {
174
+ maybePrintJson(log, json, outputData);
175
+ }
176
+ } else {
46
177
  log(`Wrote validator keystore to ${outputPath}`);
178
+ if (stakerOutput && allStakerOutputs.length > 0) {
179
+ const keystoreBaseName = basename(outputPath, '.json');
180
+ const stakerOutputPath = join(keystoreOutDir, `${keystoreBaseName}_staker_output.json`);
181
+ log(`Wrote staker output for ${allStakerOutputs.length} validator(s) to ${stakerOutputPath}`);
182
+ log('');
183
+ }
47
184
  }
48
- // Always print a concise summary of public keys (addresses and BLS pubkeys)
49
- logValidatorSummaries(log, summaries);
50
- if (!blsOnly && mnemonic && remoteSigner) {
185
+ // print a concise summary of public keys (addresses and BLS pubkeys) if no --json options was selected
186
+ if (!json) {
187
+ logValidatorSummaries(log, summaries);
188
+ }
189
+ if (mnemonic && remoteSigner && !json) {
51
190
  for(let i = 0; i < validatorCount; i++){
52
191
  const addrIdx = addressIndex + i;
53
192
  const acct = mnemonicToAccount(mnemonic, {
@@ -57,4 +196,9 @@ export async function newValidatorKeystore(options, log) {
57
196
  log(`attester address: ${acct.address} remoteSignerUrl: ${remoteSigner}`);
58
197
  }
59
198
  }
199
+ // Log staker outputs if not in JSON mode
200
+ if (!json && stakerOutput && allStakerOutputs.length > 0) {
201
+ log('\nStaker outputs:');
202
+ log(prettyPrintJSON(allStakerOutputs));
203
+ }
60
204
  }
@@ -10,18 +10,17 @@ export type ValidatorSummary = {
10
10
  export type BuildValidatorsInput = {
11
11
  validatorCount: number;
12
12
  publisherCount?: number;
13
+ publishers?: string[];
13
14
  accountIndex: number;
14
15
  baseAddressIndex: number;
15
16
  mnemonic: string;
16
17
  ikm?: string;
17
18
  blsPath?: string;
18
- blsOnly?: boolean;
19
19
  feeRecipient: AztecAddress;
20
20
  coinbase?: EthAddress;
21
21
  remoteSigner?: string;
22
- fundingAccount?: EthAddress;
23
22
  };
24
- export declare function withValidatorIndex(path: string, index: number): string;
23
+ export declare function withValidatorIndex(path: string, accountIndex?: number, addressIndex?: number): string;
25
24
  /**
26
25
  * Compute a compressed BN254 G1 public key from a private key.
27
26
  * @param privateKeyHex - Private key as 0x-prefixed hex string
@@ -57,6 +56,7 @@ export declare function writeBn254BlsKeystore(outDir: string, fileNameBase: stri
57
56
  export declare function writeBlsBn254ToFile(validators: ValidatorKeyStore[], options: {
58
57
  outDir: string;
59
58
  password: string;
59
+ blsPath?: string;
60
60
  }): Promise<void>;
61
61
  /** Writes an Ethereum JSON V3 keystore using ethers, returns absolute path */
62
62
  export declare function writeEthJsonV3Keystore(outDir: string, fileNameBase: string, password: string, privateKeyHex: string): Promise<string>;
@@ -65,4 +65,4 @@ export declare function writeEthJsonV3ToFile(validators: ValidatorKeyStore[], op
65
65
  outDir: string;
66
66
  password: string;
67
67
  }): Promise<void>;
68
- //# sourceMappingURL=shared.d.ts.map
68
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hhcmVkLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY21kcy92YWxpZGF0b3Jfa2V5cy9zaGFyZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBS0EsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDaEUsT0FBTyxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDbkQsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLGFBQWEsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQy9GLE9BQU8sS0FBSyxFQUFFLFlBQVksRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBMkRoRSxNQUFNLE1BQU0sZ0JBQWdCLEdBQUc7SUFBRSxXQUFXLENBQUMsRUFBRSxNQUFNLENBQUM7SUFBQyxXQUFXLENBQUMsRUFBRSxNQUFNLENBQUM7SUFBQyxZQUFZLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQTtDQUFFLENBQUM7QUFFdkcsTUFBTSxNQUFNLG9CQUFvQixHQUFHO0lBQ2pDLGNBQWMsRUFBRSxNQUFNLENBQUM7SUFDdkIsY0FBYyxDQUFDLEVBQUUsTUFBTSxDQUFDO0lBQ3hCLFVBQVUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDO0lBQ3RCLFlBQVksRUFBRSxNQUFNLENBQUM7SUFDckIsZ0JBQWdCLEVBQUUsTUFBTSxDQUFDO0lBQ3pCLFFBQVEsRUFBRSxNQUFNLENBQUM7SUFDakIsR0FBRyxDQUFDLEVBQUUsTUFBTSxDQUFDO0lBQ2IsT0FBTyxDQUFDLEVBQUUsTUFBTSxDQUFDO0lBQ2pCLFlBQVksRUFBRSxZQUFZLENBQUM7SUFDM0IsUUFBUSxDQUFDLEVBQUUsVUFBVSxDQUFDO0lBQ3RCLFlBQVksQ0FBQyxFQUFFLE1BQU0sQ0FBQztDQUN2QixDQUFDO0FBRUYsd0JBQWdCLGtCQUFrQixDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsWUFBWSxHQUFFLE1BQVUsRUFBRSxZQUFZLEdBQUUsTUFBVSxVQXFCbEc7QUFFRDs7OztHQUlHO0FBQ0gsd0JBQXNCLDZCQUE2QixDQUFDLGFBQWEsRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUUxRjtBQUVELHdCQUFnQixpQkFBaUIsQ0FDL0IsUUFBUSxFQUFFLE1BQU0sRUFDaEIsZ0JBQWdCLEVBQUUsTUFBTSxFQUN4QixZQUFZLEVBQUUsTUFBTSxFQUNwQixZQUFZLENBQUMsRUFBRSxNQUFNLEdBQ3BCLFVBQVUsR0FBRyxhQUFhLENBSzVCO0FBRUQsd0JBQXNCLHFCQUFxQixDQUFDLEtBQUssRUFBRSxvQkFBb0I7OztHQXVFdEU7QUFFRCx3QkFBc0IseUJBQXlCLENBQUMsT0FBTyxDQUFDLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxFQUFFLE1BQU07OztHQW9COUU7QUFFRCx3QkFBc0IsaUJBQWlCLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsT0FBTyxpQkFHdEU7QUFFRCx3QkFBZ0IscUJBQXFCLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLEVBQUUsUUFzQjlFO0FBRUQsd0JBQWdCLGNBQWMsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxPQUFPLEdBQUcsU0FBUyxFQUFFLEdBQUcsRUFBRSxPQUFPLFFBSXJGO0FBRUQ7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCx3QkFBc0IscUJBQXFCLENBQ3pDLE1BQU0sRUFBRSxNQUFNLEVBQ2QsWUFBWSxFQUFFLE1BQU0sRUFDcEIsUUFBUSxFQUFFLE1BQU0sRUFDaEIsYUFBYSxFQUFFLE1BQU0sRUFDckIsU0FBUyxFQUFFLE1BQU0sRUFDakIsY0FBYyxFQUFFLE1BQU0sR0FDckIsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQVNqQjtBQUVELHlHQUF5RztBQUN6Ryx3QkFBc0IsbUJBQW1CLENBQ3ZDLFVBQVUsRUFBRSxpQkFBaUIsRUFBRSxFQUMvQixPQUFPLEVBQUU7SUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDO0lBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQztJQUFDLE9BQU8sQ0FBQyxFQUFFLE1BQU0sQ0FBQTtDQUFFLEdBQzlELE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0F3QmY7QUFFRCw4RUFBOEU7QUFDOUUsd0JBQXNCLHNCQUFzQixDQUMxQyxNQUFNLEVBQUUsTUFBTSxFQUNkLFlBQVksRUFBRSxNQUFNLEVBQ3BCLFFBQVEsRUFBRSxNQUFNLEVBQ2hCLGFBQWEsRUFBRSxNQUFNLEdBQ3BCLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FPakI7QUFFRCxrR0FBa0c7QUFDbEcsd0JBQXNCLG9CQUFvQixDQUN4QyxVQUFVLEVBQUUsaUJBQWlCLEVBQUUsRUFDL0IsT0FBTyxFQUFFO0lBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQztJQUFDLFFBQVEsRUFBRSxNQUFNLENBQUE7Q0FBRSxHQUM1QyxPQUFPLENBQUMsSUFBSSxDQUFDLENBeUNmIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/cmds/validator_keys/shared.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/cmds/validator_keys/shared.ts"],"names":[],"mappings":"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"}
@@ -1,16 +1,78 @@
1
1
  import { prettyPrintJSON } from '@aztec/cli/utils';
2
- import { computeBn254G1PublicKeyCompressed, deriveBlsPrivateKey } from '@aztec/foundation/crypto';
2
+ import { asyncPool } from '@aztec/foundation/async-pool';
3
+ import { deriveBlsPrivateKey } from '@aztec/foundation/crypto/bls';
3
4
  import { createBn254Keystore } from '@aztec/foundation/crypto/bls/bn254_keystore';
5
+ import { computeBn254G1PublicKeyCompressed } from '@aztec/foundation/crypto/bn254';
4
6
  import { Wallet } from '@ethersproject/wallet';
5
7
  import { constants as fsConstants, mkdirSync } from 'fs';
6
8
  import { access, writeFile } from 'fs/promises';
7
- import { homedir } from 'os';
9
+ import { availableParallelism, homedir } from 'os';
8
10
  import { dirname, isAbsolute, join } from 'path';
9
11
  import { mnemonicToAccount } from 'viem/accounts';
10
- export function withValidatorIndex(path, index) {
12
+ import { Worker } from 'worker_threads';
13
+ import { defaultBlsPath } from './utils.js';
14
+ // ethers' default scrypt parameters use substantial memory, so keep worker fan-out bounded.
15
+ const maxEthKeystoreWorkers = Math.max(1, Math.min(4, availableParallelism()));
16
+ function deserializeWorkerError(error) {
17
+ const result = new Error(error.message);
18
+ result.name = error.name ?? result.name;
19
+ result.stack = error.stack;
20
+ return result;
21
+ }
22
+ function encryptEthJsonV3InWorker(privateKeyHex, password) {
23
+ return new Promise((resolve, reject)=>{
24
+ const worker = new Worker(new URL('./eth_json_v3_worker.js', import.meta.url), {
25
+ workerData: {
26
+ privateKeyHex,
27
+ password
28
+ }
29
+ });
30
+ let settled = false;
31
+ worker.once('message', (result)=>{
32
+ settled = true;
33
+ if ('json' in result) {
34
+ resolve(result.json);
35
+ } else {
36
+ reject(deserializeWorkerError(result.error));
37
+ }
38
+ });
39
+ worker.once('error', (error)=>{
40
+ settled = true;
41
+ reject(error);
42
+ });
43
+ worker.once('exit', (code)=>{
44
+ if (!settled) {
45
+ reject(new Error(`ETH JSON V3 worker stopped with exit code ${code}`));
46
+ }
47
+ });
48
+ });
49
+ }
50
+ async function encryptEthJsonV3(privateKeyHex, password) {
51
+ if (process.env.JEST_WORKER_ID !== undefined) {
52
+ return await new Wallet(privateKeyHex).encrypt(password);
53
+ }
54
+ return await encryptEthJsonV3InWorker(privateKeyHex, password);
55
+ }
56
+ export function withValidatorIndex(path, accountIndex = 0, addressIndex = 0) {
57
+ // NOTE: The legacy BLS CLI is to allow users who generated keys in 2.1.4 to be able to use the same command
58
+ // to re-generate their keys. In 2.1.5 we switched how we append addresses to the path so this is to maintain backwards compatibility.
59
+ const useLegacyBlsCli = [
60
+ 'true',
61
+ '1',
62
+ 'yes',
63
+ 'y'
64
+ ].includes(process.env.LEGACY_BLS_CLI ?? '');
65
+ const defaultBlsPathParts = defaultBlsPath.split('/');
11
66
  const parts = path.split('/');
12
- if (parts.length >= 4 && parts[0] === 'm' && parts[1] === '12381' && parts[2] === '3600') {
13
- parts[3] = String(index);
67
+ if (parts.length == defaultBlsPathParts.length && parts.every((part, index)=>part === defaultBlsPathParts[index])) {
68
+ if (useLegacyBlsCli) {
69
+ // In 2.1.4, we were using address-index in parts[3] and did NOT use account-index, check lines 32 & 84
70
+ // https://github.com/AztecProtocol/aztec-packages/blob/v2.1.4/yarn-project/cli/src/cmds/validator_keys/shared.ts
71
+ parts[3] = String(addressIndex);
72
+ } else {
73
+ parts[3] = String(accountIndex);
74
+ parts[5] = String(addressIndex);
75
+ }
14
76
  return parts.join('/');
15
77
  }
16
78
  return path;
@@ -33,29 +95,16 @@ export function deriveEthAttester(mnemonic, baseAccountIndex, addressIndex, remo
33
95
  } : '0x' + Buffer.from(acct.getHdKey().privateKey).toString('hex');
34
96
  }
35
97
  export async function buildValidatorEntries(input) {
36
- const { validatorCount, publisherCount = 0, accountIndex, baseAddressIndex, mnemonic, ikm, blsPath, blsOnly, feeRecipient, coinbase, remoteSigner, fundingAccount } = input;
37
- const defaultBlsPath = 'm/12381/3600/0/0/0';
98
+ const { validatorCount, publisherCount = 0, publishers, accountIndex, baseAddressIndex, mnemonic, ikm, blsPath, feeRecipient, coinbase, remoteSigner } = input;
38
99
  const summaries = [];
39
100
  const validators = await Promise.all(Array.from({
40
101
  length: validatorCount
41
102
  }, async (_unused, i)=>{
42
103
  const addressIndex = baseAddressIndex + i;
43
104
  const basePath = blsPath ?? defaultBlsPath;
44
- const perValidatorPath = withValidatorIndex(basePath, addressIndex);
45
- const blsPrivKey = blsOnly || ikm || mnemonic ? deriveBlsPrivateKey(mnemonic, ikm, perValidatorPath) : undefined;
105
+ const perValidatorPath = withValidatorIndex(basePath, accountIndex, addressIndex);
106
+ const blsPrivKey = ikm || mnemonic ? deriveBlsPrivateKey(mnemonic, ikm, perValidatorPath) : undefined;
46
107
  const blsPubCompressed = blsPrivKey ? await computeBlsPublicKeyCompressed(blsPrivKey) : undefined;
47
- if (blsOnly) {
48
- const attester = {
49
- bls: blsPrivKey
50
- };
51
- summaries.push({
52
- attesterBls: blsPubCompressed
53
- });
54
- return {
55
- attester,
56
- feeRecipient
57
- };
58
- }
59
108
  const ethAttester = deriveEthAttester(mnemonic, accountIndex, addressIndex, remoteSigner);
60
109
  const attester = blsPrivKey ? {
61
110
  eth: ethAttester,
@@ -63,7 +112,10 @@ export async function buildValidatorEntries(input) {
63
112
  } : ethAttester;
64
113
  let publisherField;
65
114
  const publisherAddresses = [];
66
- if (publisherCount > 0) {
115
+ if (publishers && publishers.length > 0) {
116
+ publisherAddresses.push(...publishers);
117
+ publisherField = publishers.length === 1 ? publishers[0] : publishers;
118
+ } else if (publisherCount > 0) {
67
119
  const publishersBaseIndex = baseAddressIndex + validatorCount + i * publisherCount;
68
120
  const publisherAccounts = Array.from({
69
121
  length: publisherCount
@@ -97,8 +149,7 @@ export async function buildValidatorEntries(input) {
97
149
  publisher: publisherField
98
150
  } : {},
99
151
  feeRecipient,
100
- coinbase,
101
- fundingAccount
152
+ coinbase: coinbase ?? attesterEthAddress
102
153
  };
103
154
  }));
104
155
  return {
@@ -181,7 +232,7 @@ export function maybePrintJson(log, jsonFlag, obj) {
181
232
  mkdirSync(outDir, {
182
233
  recursive: true
183
234
  });
184
- const keystore = createBn254Keystore(password, privateKeyHex, pubkeyHex, derivationPath);
235
+ const keystore = await createBn254Keystore(password, privateKeyHex, pubkeyHex, derivationPath);
185
236
  const safeBase = fileNameBase.replace(/[^a-zA-Z0-9_-]/g, '_');
186
237
  const outPath = join(outDir, `keystore-${safeBase}.json`);
187
238
  await writeFile(outPath, JSON.stringify(keystore, null, 2), {
@@ -190,19 +241,18 @@ export function maybePrintJson(log, jsonFlag, obj) {
190
241
  return outPath;
191
242
  }
192
243
  /** Replace plaintext BLS keys in validators with { path, password } pointing to BN254 keystore files. */ export async function writeBlsBn254ToFile(validators, options) {
193
- for(let i = 0; i < validators.length; i++){
194
- const v = validators[i];
244
+ await Promise.all(validators.map(async (v, i)=>{
195
245
  if (!v || typeof v !== 'object' || !('attester' in v)) {
196
- continue;
246
+ return;
197
247
  }
198
248
  const att = v.attester;
199
249
  // Shapes: { bls: <hex> } or { eth: <ethAccount>, bls?: <hex> } or plain EthAccount
200
250
  const blsKey = typeof att === 'object' && 'bls' in att ? att.bls : undefined;
201
251
  if (!blsKey || typeof blsKey !== 'string') {
202
- continue;
252
+ return;
203
253
  }
204
254
  const pub = await computeBlsPublicKeyCompressed(blsKey);
205
- const path = 'm/12381/3600/0/0/0';
255
+ const path = options.blsPath ?? defaultBlsPath;
206
256
  const fileBase = `${String(i + 1)}_${pub.slice(2, 18)}`;
207
257
  const keystorePath = await writeBn254BlsKeystore(options.outDir, fileBase, options.password, blsKey, pub, path);
208
258
  if (typeof att === 'object') {
@@ -211,15 +261,14 @@ export function maybePrintJson(log, jsonFlag, obj) {
211
261
  password: options.password
212
262
  };
213
263
  }
214
- }
264
+ }));
215
265
  }
216
266
  /** Writes an Ethereum JSON V3 keystore using ethers, returns absolute path */ export async function writeEthJsonV3Keystore(outDir, fileNameBase, password, privateKeyHex) {
217
267
  const safeBase = fileNameBase.replace(/[^a-zA-Z0-9_-]/g, '_');
218
268
  mkdirSync(outDir, {
219
269
  recursive: true
220
270
  });
221
- const wallet = new Wallet(privateKeyHex);
222
- const json = await wallet.encrypt(password);
271
+ const json = await encryptEthJsonV3(privateKeyHex, password);
223
272
  const outPath = join(outDir, `keystore-eth-${safeBase}.json`);
224
273
  await writeFile(outPath, json, {
225
274
  encoding: 'utf-8'
@@ -227,16 +276,18 @@ export function maybePrintJson(log, jsonFlag, obj) {
227
276
  return outPath;
228
277
  }
229
278
  /** Replace plaintext ETH keys in validators with { path, password } pointing to JSON V3 files. */ export async function writeEthJsonV3ToFile(validators, options) {
230
- const maybeEncryptEth = async (account, label)=>{
279
+ const tasks = [];
280
+ const maybeQueueEncryptEth = (account, label, setEncryptedAccount)=>{
231
281
  if (typeof account === 'string' && account.startsWith('0x') && account.length === 66) {
232
- const fileBase = `${label}_${account.slice(2, 10)}`;
233
- const p = await writeEthJsonV3Keystore(options.outDir, fileBase, options.password, account);
234
- return {
235
- path: p,
236
- password: options.password
237
- };
282
+ tasks.push(async ()=>{
283
+ const fileBase = `${label}_${account.slice(2, 10)}`;
284
+ const path = await writeEthJsonV3Keystore(options.outDir, fileBase, options.password, account);
285
+ setEncryptedAccount({
286
+ path,
287
+ password: options.password
288
+ });
289
+ });
238
290
  }
239
- return account;
240
291
  };
241
292
  for(let i = 0; i < validators.length; i++){
242
293
  const v = validators[i];
@@ -246,26 +297,21 @@ export function maybePrintJson(log, jsonFlag, obj) {
246
297
  // attester may be string (eth), object with eth, or remote signer
247
298
  const att = v.attester;
248
299
  if (typeof att === 'string') {
249
- v.attester = await maybeEncryptEth(att, `attester_${i + 1}`);
300
+ maybeQueueEncryptEth(att, `attester_${i + 1}`, (account)=>v.attester = account);
250
301
  } else if (att && typeof att === 'object' && 'eth' in att) {
251
- att.eth = await maybeEncryptEth(att.eth, `attester_${i + 1}`);
302
+ maybeQueueEncryptEth(att.eth, `attester_${i + 1}`, (account)=>att.eth = account);
252
303
  }
253
304
  // publisher can be single or array
254
305
  if ('publisher' in v) {
255
306
  const pub = v.publisher;
256
307
  if (Array.isArray(pub)) {
257
- const out = [];
258
308
  for(let j = 0; j < pub.length; j++){
259
- out.push(await maybeEncryptEth(pub[j], `publisher_${i + 1}_${j + 1}`));
309
+ maybeQueueEncryptEth(pub[j], `publisher_${i + 1}_${j + 1}`, (account)=>pub[j] = account);
260
310
  }
261
- v.publisher = out;
262
311
  } else if (pub !== undefined) {
263
- v.publisher = await maybeEncryptEth(pub, `publisher_${i + 1}`);
312
+ maybeQueueEncryptEth(pub, `publisher_${i + 1}`, (account)=>v.publisher = account);
264
313
  }
265
314
  }
266
- // Optional fundingAccount within validator
267
- if ('fundingAccount' in v) {
268
- v.fundingAccount = await maybeEncryptEth(v.fundingAccount, `funding_${i + 1}`);
269
- }
270
315
  }
316
+ await asyncPool(maxEthKeystoreWorkers, tasks, (task)=>task());
271
317
  }
@@ -0,0 +1,38 @@
1
+ import { GSEContract } from '@aztec/ethereum/contracts';
2
+ import type { EthAddress } from '@aztec/foundation/eth-address';
3
+ import type { LogFn } from '@aztec/foundation/log';
4
+ import type { AttesterAccounts } from '@aztec/node-keystore/types';
5
+ export type StakerOptions = {
6
+ from: string;
7
+ password?: string;
8
+ output?: string;
9
+ gseAddress: EthAddress;
10
+ l1RpcUrls: string[];
11
+ l1ChainId: number;
12
+ };
13
+ export type StakerOutput = {
14
+ attester: string;
15
+ publicKeyG1: {
16
+ x: string;
17
+ y: string;
18
+ };
19
+ publicKeyG2: {
20
+ x0: string;
21
+ x1: string;
22
+ y0: string;
23
+ y1: string;
24
+ };
25
+ proofOfPossession: {
26
+ x: string;
27
+ y: string;
28
+ };
29
+ };
30
+ /**
31
+ * Process AttesterAccounts (which can be a single attester, array, or mnemonic)
32
+ */
33
+ export declare function processAttesterAccounts(attesterAccounts: AttesterAccounts, gse: GSEContract, password?: string): Promise<StakerOutput[]>;
34
+ /**
35
+ * Main staker command function
36
+ */
37
+ export declare function generateStakerJson(options: StakerOptions, log: LogFn): Promise<void>;
38
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3Rha2VyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY21kcy92YWxpZGF0b3Jfa2V5cy9zdGFrZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBSXhELE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ2hFLE9BQU8sS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRW5ELE9BQU8sS0FBSyxFQUVWLGdCQUFnQixFQUtqQixNQUFNLDRCQUE0QixDQUFDO0FBUXBDLE1BQU0sTUFBTSxhQUFhLEdBQUc7SUFDMUIsSUFBSSxFQUFFLE1BQU0sQ0FBQztJQUNiLFFBQVEsQ0FBQyxFQUFFLE1BQU0sQ0FBQztJQUNsQixNQUFNLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDaEIsVUFBVSxFQUFFLFVBQVUsQ0FBQztJQUN2QixTQUFTLEVBQUUsTUFBTSxFQUFFLENBQUM7SUFDcEIsU0FBUyxFQUFFLE1BQU0sQ0FBQztDQUNuQixDQUFDO0FBRUYsTUFBTSxNQUFNLFlBQVksR0FBRztJQUN6QixRQUFRLEVBQUUsTUFBTSxDQUFDO0lBQ2pCLFdBQVcsRUFBRTtRQUNYLENBQUMsRUFBRSxNQUFNLENBQUM7UUFDVixDQUFDLEVBQUUsTUFBTSxDQUFDO0tBQ1gsQ0FBQztJQUNGLFdBQVcsRUFBRTtRQUNYLEVBQUUsRUFBRSxNQUFNLENBQUM7UUFDWCxFQUFFLEVBQUUsTUFBTSxDQUFDO1FBQ1gsRUFBRSxFQUFFLE1BQU0sQ0FBQztRQUNYLEVBQUUsRUFBRSxNQUFNLENBQUM7S0FDWixDQUFDO0lBQ0YsaUJBQWlCLEVBQUU7UUFDakIsQ0FBQyxFQUFFLE1BQU0sQ0FBQztRQUNWLENBQUMsRUFBRSxNQUFNLENBQUM7S0FDWCxDQUFDO0NBQ0gsQ0FBQztBQTJLRjs7R0FFRztBQUNILHdCQUFzQix1QkFBdUIsQ0FDM0MsZ0JBQWdCLEVBQUUsZ0JBQWdCLEVBQ2xDLEdBQUcsRUFBRSxXQUFXLEVBQ2hCLFFBQVEsQ0FBQyxFQUFFLE1BQU0sR0FDaEIsT0FBTyxDQUFDLFlBQVksRUFBRSxDQUFDLENBcUJ6QjtBQUVEOztHQUVHO0FBQ0gsd0JBQXNCLGtCQUFrQixDQUFDLE9BQU8sRUFBRSxhQUFhLEVBQUUsR0FBRyxFQUFFLEtBQUssR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBK0MxRiJ9
@@ -0,0 +1 @@
1
+ {"version":3,"file":"staker.d.ts","sourceRoot":"","sources":["../../../src/cmds/validator_keys/staker.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAIxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,KAAK,EAEV,gBAAgB,EAKjB,MAAM,4BAA4B,CAAC;AAQpC,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE;QACX,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;KACX,CAAC;IACF,WAAW,EAAE;QACX,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC;IACF,iBAAiB,EAAE;QACjB,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;KACX,CAAC;CACH,CAAC;AA2KF;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,gBAAgB,EAAE,gBAAgB,EAClC,GAAG,EAAE,WAAW,EAChB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,YAAY,EAAE,CAAC,CAqBzB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CA+C1F"}