Derive more defaults in chain config (#3745)

### Description

- Attempt to detect RPC URL, chain name, and chain ID

### Testing

```sh
Creating a new chain config
? Detected rpc url as http://localhost:8545, is this correct? no
? Enter http or https rpc url http://localhost:8546
? Detected chain name as anvil8546, is this correct? yes
? Detected chain id as 31338, is this correct? yes
? Do you want to set block or gas properties for this chain config?(optional) (y/N)
```
kunal/avs-contract-deployment
Yorke Rhodes 7 months ago committed by GitHub
parent 76619d0729
commit 2b7dfe27e1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 5
      .changeset/lemon-horses-swim.md
  2. 50
      typescript/cli/src/config/chain.ts
  3. 21
      typescript/cli/src/utils/chains.ts

@ -0,0 +1,5 @@
---
'@hyperlane-xyz/cli': patch
---
Improve defaults in chain config command

@ -1,10 +1,12 @@
import { confirm, input } from '@inquirer/prompts';
import { ethers } from 'ethers';
import { ChainMetadata, ChainMetadataSchema } from '@hyperlane-xyz/sdk';
import { ProtocolType } from '@hyperlane-xyz/utils';
import { CommandContext } from '../context/types.js';
import { errorRed, log, logBlue, logGreen } from '../logger.js';
import { detectAndConfirmOrPrompt } from '../utils/chains.js';
import { readYamlOrJson } from '../utils/files.js';
export function readChainConfigs(filePath: string) {
@ -38,22 +40,52 @@ export async function createChainConfig({
context: CommandContext;
}) {
logBlue('Creating a new chain config');
const name = await input({
message: 'Enter chain name (one word, lower case)',
});
const chainId = await input({ message: 'Enter chain id (number)' });
const domainId = chainId;
const rpcUrl = await input({ message: 'Enter http or https rpc url' });
const rpcUrl = await detectAndConfirmOrPrompt(
async () => {
await new ethers.providers.JsonRpcProvider().getNetwork();
return ethers.providers.JsonRpcProvider.defaultUrl();
},
'rpc url',
'Enter http or https',
);
const provider = new ethers.providers.JsonRpcProvider(rpcUrl);
const name = await detectAndConfirmOrPrompt(
async () => {
const clientName = await provider.send('web3_clientVersion', []);
const port = rpcUrl.split(':').slice(-1);
const client = clientName.split('/')[0];
return `${client}${port}`;
},
'chain name',
'Enter (one word, lower case)',
);
const chainId = parseInt(
await detectAndConfirmOrPrompt(
async () => {
const network = await provider.getNetwork();
return network.chainId.toString();
},
'chain id',
'Enter a (number)',
),
10,
);
const metadata: ChainMetadata = {
name,
chainId: parseInt(chainId, 10),
domainId: parseInt(domainId, 10),
chainId,
domainId: chainId,
protocol: ProtocolType.Ethereum,
rpcUrls: [{ http: rpcUrl }],
};
const wantAdvancedConfig = await confirm({
default: false,
message:
'Do you want to set block or gas properties for this chain config?(optional)',
'Do you want to set block or gas properties for this chain config?',
});
if (wantAdvancedConfig) {
const wantBlockConfig = await confirm({

@ -1,4 +1,4 @@
import { Separator, checkbox } from '@inquirer/prompts';
import { Separator, checkbox, confirm, input } from '@inquirer/prompts';
import select from '@inquirer/select';
import chalk from 'chalk';
@ -73,3 +73,22 @@ function handleNewChain(chainNames: string[]) {
process.exit(0);
}
}
export async function detectAndConfirmOrPrompt(
detect: () => Promise<string>,
label: string,
prompt: string,
): Promise<string> {
let detectedValue: string | undefined;
try {
detectedValue = await detect();
const confirmed = await confirm({
message: `Detected ${label} as ${detectedValue}, is this correct?`,
});
if (confirmed) {
return detectedValue;
}
// eslint-disable-next-line no-empty
} catch (e) {}
return input({ message: `${prompt} ${label}`, default: detectedValue });
}

Loading…
Cancel
Save