@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.
- package/README.md +1 -1
- package/dest/cmds/aztec_node/block_number.d.ts +1 -1
- package/dest/cmds/aztec_node/block_number.js +1 -1
- package/dest/cmds/aztec_node/get_block.d.ts +1 -1
- package/dest/cmds/aztec_node/get_block.d.ts.map +1 -1
- package/dest/cmds/aztec_node/get_block.js +2 -1
- package/dest/cmds/aztec_node/get_current_min_fee.d.ts +3 -0
- package/dest/cmds/aztec_node/get_current_min_fee.d.ts.map +1 -0
- package/dest/cmds/aztec_node/{get_current_base_fee.js → get_current_min_fee.js} +2 -2
- package/dest/cmds/aztec_node/get_l1_to_l2_message_witness.d.ts +1 -1
- package/dest/cmds/aztec_node/get_logs.d.ts +30 -3
- package/dest/cmds/aztec_node/get_logs.d.ts.map +1 -1
- package/dest/cmds/aztec_node/get_logs.js +39 -29
- package/dest/cmds/aztec_node/get_node_info.d.ts +1 -1
- package/dest/cmds/aztec_node/get_node_info.d.ts.map +1 -1
- package/dest/cmds/aztec_node/get_node_info.js +0 -2
- package/dest/cmds/aztec_node/index.d.ts +1 -1
- package/dest/cmds/aztec_node/index.d.ts.map +1 -1
- package/dest/cmds/aztec_node/index.js +16 -6
- package/dest/cmds/contracts/index.d.ts +1 -1
- package/dest/cmds/contracts/inspect_contract.d.ts +1 -1
- package/dest/cmds/contracts/inspect_contract.d.ts.map +1 -1
- package/dest/cmds/contracts/inspect_contract.js +4 -10
- package/dest/cmds/contracts/parse_parameter_struct.d.ts +1 -1
- package/dest/cmds/infrastructure/index.d.ts +1 -1
- package/dest/cmds/infrastructure/index.d.ts.map +1 -1
- package/dest/cmds/infrastructure/index.js +0 -1
- package/dest/cmds/infrastructure/sequencers.d.ts +1 -2
- package/dest/cmds/infrastructure/sequencers.d.ts.map +1 -1
- package/dest/cmds/infrastructure/sequencers.js +11 -4
- package/dest/cmds/infrastructure/setup_l2_contract.d.ts +1 -1
- package/dest/cmds/infrastructure/setup_l2_contract.d.ts.map +1 -1
- package/dest/cmds/infrastructure/setup_l2_contract.js +12 -7
- package/dest/cmds/l1/advance_epoch.d.ts +1 -1
- package/dest/cmds/l1/assume_proven_through.d.ts +3 -2
- package/dest/cmds/l1/assume_proven_through.d.ts.map +1 -1
- package/dest/cmds/l1/assume_proven_through.js +3 -4
- package/dest/cmds/l1/bridge_erc20.d.ts +1 -1
- package/dest/cmds/l1/bridge_erc20.d.ts.map +1 -1
- package/dest/cmds/l1/bridge_erc20.js +2 -1
- package/dest/cmds/l1/compute_genesis_values.d.ts +4 -0
- package/dest/cmds/l1/compute_genesis_values.d.ts.map +1 -0
- package/dest/cmds/l1/compute_genesis_values.js +17 -0
- package/dest/cmds/l1/create_l1_account.d.ts +1 -1
- package/dest/cmds/l1/deploy_l1_contracts_cmd.d.ts +4 -0
- package/dest/cmds/l1/deploy_l1_contracts_cmd.d.ts.map +1 -0
- package/dest/cmds/l1/{deploy_l1_contracts.js → deploy_l1_contracts_cmd.js} +39 -5
- package/dest/cmds/l1/deploy_new_rollup.d.ts +4 -4
- package/dest/cmds/l1/deploy_new_rollup.d.ts.map +1 -1
- package/dest/cmds/l1/deploy_new_rollup.js +4 -6
- package/dest/cmds/l1/get_l1_addresses.d.ts +1 -1
- package/dest/cmds/l1/get_l1_addresses.d.ts.map +1 -1
- package/dest/cmds/l1/get_l1_addresses.js +5 -2
- package/dest/cmds/l1/get_l1_balance.d.ts +1 -1
- package/dest/cmds/l1/get_l1_balance.js +4 -2
- package/dest/cmds/l1/governance_utils.d.ts +5 -5
- package/dest/cmds/l1/governance_utils.d.ts.map +1 -1
- package/dest/cmds/l1/governance_utils.js +3 -1
- package/dest/cmds/l1/index.d.ts +1 -2
- package/dest/cmds/l1/index.d.ts.map +1 -1
- package/dest/cmds/l1/index.js +17 -10
- package/dest/cmds/l1/prover_stats.d.ts +1 -1
- package/dest/cmds/l1/prover_stats.d.ts.map +1 -1
- package/dest/cmds/l1/prover_stats.js +32 -30
- package/dest/cmds/l1/trigger_seed_snapshot.d.ts +2 -2
- package/dest/cmds/l1/trigger_seed_snapshot.d.ts.map +1 -1
- package/dest/cmds/l1/trigger_seed_snapshot.js +2 -1
- package/dest/cmds/l1/update_l1_validators.d.ts +7 -7
- package/dest/cmds/l1/update_l1_validators.d.ts.map +1 -1
- package/dest/cmds/l1/update_l1_validators.js +58 -20
- package/dest/cmds/misc/compute_selector.d.ts +1 -1
- package/dest/cmds/misc/example_contracts.d.ts +1 -1
- package/dest/cmds/misc/generate_bootnode_enr.d.ts +1 -1
- package/dest/cmds/misc/generate_p2p_private_key.d.ts +1 -1
- package/dest/cmds/misc/generate_secret_and_hash.d.ts +1 -1
- package/dest/cmds/misc/generate_secret_and_hash.js +1 -1
- package/dest/cmds/misc/generate_secret_key.d.ts +1 -1
- package/dest/cmds/misc/get_canonical_sponsored_fpc_address.d.ts +1 -1
- package/dest/cmds/misc/index.d.ts +1 -1
- package/dest/cmds/misc/index.d.ts.map +1 -1
- package/dest/cmds/misc/index.js +1 -1
- package/dest/cmds/misc/update/common.d.ts +1 -1
- package/dest/cmds/misc/update/github.d.ts +1 -1
- package/dest/cmds/misc/update/noir.d.ts +1 -1
- package/dest/cmds/misc/update/npm.d.ts +1 -1
- package/dest/cmds/misc/update/npm.js +1 -1
- package/dest/cmds/misc/update/utils.d.ts +1 -1
- package/dest/cmds/misc/update.d.ts +1 -1
- package/dest/cmds/validator_keys/add.d.ts +1 -1
- package/dest/cmds/validator_keys/add.d.ts.map +1 -1
- package/dest/cmds/validator_keys/add.js +20 -7
- package/dest/cmds/validator_keys/eth_json_v3_worker.d.ts +2 -0
- package/dest/cmds/validator_keys/eth_json_v3_worker.d.ts.map +1 -0
- package/dest/cmds/validator_keys/eth_json_v3_worker.js +27 -0
- package/dest/cmds/validator_keys/generate_bls_keypair.d.ts +1 -1
- package/dest/cmds/validator_keys/generate_bls_keypair.d.ts.map +1 -1
- package/dest/cmds/validator_keys/generate_bls_keypair.js +3 -2
- package/dest/cmds/validator_keys/index.d.ts +1 -1
- package/dest/cmds/validator_keys/index.d.ts.map +1 -1
- package/dest/cmds/validator_keys/index.js +17 -4
- package/dest/cmds/validator_keys/new.d.ts +12 -4
- package/dest/cmds/validator_keys/new.d.ts.map +1 -1
- package/dest/cmds/validator_keys/new.js +163 -19
- package/dest/cmds/validator_keys/shared.d.ts +4 -4
- package/dest/cmds/validator_keys/shared.d.ts.map +1 -1
- package/dest/cmds/validator_keys/shared.js +97 -51
- package/dest/cmds/validator_keys/staker.d.ts +38 -0
- package/dest/cmds/validator_keys/staker.d.ts.map +1 -0
- package/dest/cmds/validator_keys/staker.js +210 -0
- package/dest/cmds/validator_keys/utils.d.ts +25 -0
- package/dest/cmds/validator_keys/utils.d.ts.map +1 -0
- package/dest/cmds/validator_keys/utils.js +52 -0
- package/dest/config/cached_fetch.d.ts +19 -10
- package/dest/config/cached_fetch.d.ts.map +1 -1
- package/dest/config/cached_fetch.js +110 -32
- package/dest/config/chain_l2_config.d.ts +18 -38
- package/dest/config/chain_l2_config.d.ts.map +1 -1
- package/dest/config/chain_l2_config.js +48 -463
- package/dest/config/enrich_env.d.ts +1 -1
- package/dest/config/generated/networks.d.ts +239 -0
- package/dest/config/generated/networks.d.ts.map +1 -0
- package/dest/config/generated/networks.js +240 -0
- package/dest/config/get_l1_config.d.ts +3 -2
- package/dest/config/get_l1_config.d.ts.map +1 -1
- package/dest/config/get_l1_config.js +3 -1
- package/dest/config/index.d.ts +1 -1
- package/dest/config/network_config.d.ts +7 -4
- package/dest/config/network_config.d.ts.map +1 -1
- package/dest/config/network_config.js +70 -30
- package/dest/utils/aztec.d.ts +7 -14
- package/dest/utils/aztec.d.ts.map +1 -1
- package/dest/utils/aztec.js +19 -41
- package/dest/utils/commands.d.ts +20 -11
- package/dest/utils/commands.d.ts.map +1 -1
- package/dest/utils/commands.js +26 -15
- package/dest/utils/encoding.d.ts +1 -1
- package/dest/utils/encoding.js +1 -1
- package/dest/utils/github.d.ts +1 -1
- package/dest/utils/index.d.ts +1 -1
- package/dest/utils/inspect.d.ts +3 -2
- package/dest/utils/inspect.d.ts.map +1 -1
- package/dest/utils/inspect.js +15 -12
- package/dest/utils/setup_contracts.d.ts +1 -1
- package/package.json +44 -31
- package/public_include_metric_prefixes.json +1 -0
- package/src/cmds/aztec_node/block_number.ts +1 -1
- package/src/cmds/aztec_node/get_block.ts +2 -1
- package/src/cmds/aztec_node/{get_current_base_fee.ts → get_current_min_fee.ts} +2 -2
- package/src/cmds/aztec_node/get_logs.ts +70 -37
- package/src/cmds/aztec_node/get_node_info.ts +0 -2
- package/src/cmds/aztec_node/index.ts +16 -11
- package/src/cmds/contracts/inspect_contract.ts +4 -11
- package/src/cmds/infrastructure/index.ts +0 -1
- package/src/cmds/infrastructure/sequencers.ts +7 -5
- package/src/cmds/infrastructure/setup_l2_contract.ts +12 -7
- package/src/cmds/l1/assume_proven_through.ts +4 -4
- package/src/cmds/l1/bridge_erc20.ts +2 -1
- package/src/cmds/l1/compute_genesis_values.ts +29 -0
- package/src/cmds/l1/{deploy_l1_contracts.ts → deploy_l1_contracts_cmd.ts} +39 -23
- package/src/cmds/l1/deploy_new_rollup.ts +5 -12
- package/src/cmds/l1/get_l1_addresses.ts +4 -2
- package/src/cmds/l1/get_l1_balance.ts +2 -2
- package/src/cmds/l1/governance_utils.ts +3 -8
- package/src/cmds/l1/index.ts +30 -21
- package/src/cmds/l1/prover_stats.ts +42 -31
- package/src/cmds/l1/trigger_seed_snapshot.ts +2 -1
- package/src/cmds/l1/update_l1_validators.ts +52 -32
- package/src/cmds/misc/generate_secret_and_hash.ts +1 -1
- package/src/cmds/misc/index.ts +1 -1
- package/src/cmds/misc/update/npm.ts +1 -1
- package/src/cmds/validator_keys/add.ts +20 -10
- package/src/cmds/validator_keys/eth_json_v3_worker.ts +30 -0
- package/src/cmds/validator_keys/generate_bls_keypair.ts +3 -2
- package/src/cmds/validator_keys/index.ts +85 -25
- package/src/cmds/validator_keys/new.ts +211 -25
- package/src/cmds/validator_keys/shared.ts +117 -60
- package/src/cmds/validator_keys/staker.ts +301 -0
- package/src/cmds/validator_keys/utils.ts +81 -0
- package/src/config/cached_fetch.ts +119 -31
- package/src/config/chain_l2_config.ts +47 -602
- package/src/config/generated/networks.ts +244 -0
- package/src/config/get_l1_config.ts +4 -1
- package/src/config/network_config.ts +80 -31
- package/src/utils/aztec.ts +30 -95
- package/src/utils/commands.ts +29 -15
- package/src/utils/encoding.ts +1 -1
- package/src/utils/inspect.ts +13 -10
- package/dest/cmds/aztec_node/get_current_base_fee.d.ts +0 -3
- package/dest/cmds/aztec_node/get_current_base_fee.d.ts.map +0 -1
- package/dest/cmds/l1/deploy_l1_contracts.d.ts +0 -4
- 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 {
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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 (
|
|
29
|
-
const
|
|
117
|
+
if (shouldEncryptKeystores) {
|
|
118
|
+
const encryptedKeystoreOutDir = encryptedKeystoreDir && encryptedKeystoreDir.length > 0 ? encryptedKeystoreDir : keystoreOutDir;
|
|
30
119
|
await writeEthJsonV3ToFile(validators, {
|
|
31
|
-
outDir:
|
|
32
|
-
password
|
|
120
|
+
outDir: encryptedKeystoreOutDir,
|
|
121
|
+
password: ethPassword
|
|
33
122
|
});
|
|
34
123
|
await writeBlsBn254ToFile(validators, {
|
|
35
|
-
outDir:
|
|
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
|
-
|
|
45
|
-
|
|
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
|
-
//
|
|
49
|
-
|
|
50
|
-
|
|
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,
|
|
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=
|
|
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":"
|
|
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 {
|
|
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
|
-
|
|
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
|
|
13
|
-
|
|
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,
|
|
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 =
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
252
|
+
return;
|
|
203
253
|
}
|
|
204
254
|
const pub = await computeBlsPublicKeyCompressed(blsKey);
|
|
205
|
-
const path =
|
|
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
|
|
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
|
|
279
|
+
const tasks = [];
|
|
280
|
+
const maybeQueueEncryptEth = (account, label, setEncryptedAccount)=>{
|
|
231
281
|
if (typeof account === 'string' && account.startsWith('0x') && account.length === 66) {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
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
|
-
|
|
300
|
+
maybeQueueEncryptEth(att, `attester_${i + 1}`, (account)=>v.attester = account);
|
|
250
301
|
} else if (att && typeof att === 'object' && 'eth' in att) {
|
|
251
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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"}
|