Skip to content

Commit ce0b173

Browse files
refactor: warp config loading (hyperlane-xyz#6173)
### Description This PR refactors the warp route configuration functions to use object parameters instead of positional parameters, improving API clarity and flexibility. The main changes include: - Modified `readWarpRouteDeployConfig` to accept an object parameter with named properties - Updated `readWarpCoreConfig` with similar parameter style changes - Added utility functions for handling warp route configuration in various scenarios - Enhanced context types with warp configuration properties ### Drive-by changes - Added new `getWarpRouteDeployConfig` utility function - Added `useProvidedWarpRouteIdOrPrompt` helper function - Improved error messaging and assertions Diff with last PR: hyperlane-xyz/hyperlane-monorepo@upgrade/registry-14.0.0...refactor/warp-config-loading ### Related issues hyperlane-xyz#5244 hyperlane-xyz#5922 ### Backward compatibility Yes - Internal refactoring only, existing CLI commands work the same way ### Testing Manual testing of CLI commands
1 parent 1770318 commit ce0b173

7 files changed

Lines changed: 215 additions & 67 deletions

File tree

.changeset/little-houses-crash.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@hyperlane-xyz/cli': minor
3+
---
4+
5+
Refactored warp route configuration functions to use object parameters instead of positional parameters for improved clarity and flexibility.

typescript/cli/src/commands/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ const validateWarpCommand: CommandModuleWithContext<{ path: string }> = {
9898
path: inputFileCommandOption(),
9999
},
100100
handler: async ({ path, context }) => {
101-
await readWarpRouteDeployConfig(path, context);
101+
await readWarpRouteDeployConfig({ context, filePath: path });
102102
logGreen('Config is valid');
103103
process.exit(0);
104104
},

typescript/cli/src/commands/warp.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,10 @@ export const apply: CommandModuleWithWriteContext<{
120120

121121
if (strategyUrl)
122122
ChainSubmissionStrategySchema.parse(readYamlOrJson(strategyUrl));
123-
const warpDeployConfig = await readWarpRouteDeployConfig(config, context);
123+
const warpDeployConfig = await readWarpRouteDeployConfig({
124+
filePath: config,
125+
context,
126+
});
124127

125128
await runWarpRouteApply({
126129
context,

typescript/cli/src/config/warp.ts

Lines changed: 100 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { stringify as yamlStringify } from 'yaml';
44
import {
55
ChainMap,
66
DeployedOwnableConfig,
7+
HypERC20Deployer,
78
IsmConfig,
89
IsmType,
910
MailboxClientConfig,
@@ -22,13 +23,15 @@ import { errorRed, log, logBlue, logGreen } from '../logger.js';
2223
import { runMultiChainSelectionStep } from '../utils/chains.js';
2324
import {
2425
indentYamlOrJson,
26+
isFile,
2527
readYamlOrJson,
2628
writeYamlOrJson,
2729
} from '../utils/files.js';
2830
import {
2931
detectAndConfirmOrPrompt,
3032
setProxyAdminConfig,
3133
} from '../utils/input.js';
34+
import { useProvidedWarpRouteIdOrPrompt } from '../utils/warp.js';
3235

3336
import { createAdvancedIsmConfig } from './ism.js';
3437

@@ -88,13 +91,24 @@ export async function fillDefaults(
8891
);
8992
}
9093

91-
export async function readWarpRouteDeployConfig(
92-
filePath: string,
93-
context: CommandContext,
94-
): Promise<WarpRouteDeployConfigMailboxRequired> {
95-
let config = readYamlOrJson(filePath);
96-
if (!config)
97-
throw new Error(`No warp route deploy config found at ${filePath}`);
94+
export async function readWarpRouteDeployConfig({
95+
context,
96+
...args
97+
}:
98+
| {
99+
context: CommandContext;
100+
warpRouteId: string;
101+
}
102+
| {
103+
context: CommandContext;
104+
filePath: string;
105+
}): Promise<WarpRouteDeployConfigMailboxRequired> {
106+
let config =
107+
'filePath' in args
108+
? readYamlOrJson(args.filePath)
109+
: await context.registry.getWarpDeployConfig(args.warpRouteId);
110+
111+
assert(config, `No warp route deploy config found!`);
98112

99113
config = await fillDefaults(context, config as any);
100114

@@ -112,7 +126,7 @@ export async function createWarpRouteDeployConfig({
112126
advanced = false,
113127
}: {
114128
context: CommandContext;
115-
outPath: string;
129+
outPath?: string;
116130
advanced: boolean;
117131
}) {
118132
logBlue('Creating a new warp route deployment config...');
@@ -253,7 +267,21 @@ export async function createWarpRouteDeployConfig({
253267
const warpRouteDeployConfig = WarpRouteDeployConfigSchema.parse(result);
254268
logBlue(`Warp Route config is valid, writing to file ${outPath}:\n`);
255269
log(indentYamlOrJson(yamlStringify(warpRouteDeployConfig, null, 2), 4));
256-
writeYamlOrJson(outPath, warpRouteDeployConfig, 'yaml');
270+
if (outPath) {
271+
writeYamlOrJson(outPath, warpRouteDeployConfig, 'yaml');
272+
} else {
273+
const tokenMetadata = await HypERC20Deployer.deriveTokenMetadata(
274+
context.multiProvider,
275+
warpRouteDeployConfig,
276+
);
277+
assert(
278+
tokenMetadata?.symbol,
279+
'Error deriving token metadata, please check the provided token addresses',
280+
);
281+
await context.registry.addWarpRouteConfig(warpRouteDeployConfig, {
282+
symbol: tokenMetadata.symbol,
283+
});
284+
}
257285
logGreen('✅ Successfully created new warp route deployment config.');
258286
} catch (e) {
259287
errorRed(
@@ -269,9 +297,29 @@ function restrictChoices(typeChoices: TokenType[]) {
269297

270298
// Note, this is different than the function above which reads a config
271299
// for a DEPLOYMENT. This gets a config for using a warp route (aka WarpCoreConfig)
272-
export function readWarpCoreConfig(filePath: string): WarpCoreConfig {
273-
const config = readYamlOrJson(filePath);
274-
if (!config) throw new Error(`No warp route config found at ${filePath}`);
300+
export async function readWarpCoreConfig(
301+
args:
302+
| {
303+
context: CommandContext;
304+
warpRouteId: string;
305+
}
306+
| {
307+
filePath: string;
308+
},
309+
): Promise<WarpCoreConfig> {
310+
let config: WarpCoreConfig | null = null;
311+
const readWithFilePath = 'filePath' in args;
312+
if (readWithFilePath) {
313+
config = readYamlOrJson(args.filePath);
314+
} else {
315+
config = await args.context.registry.getWarpRoute(args.warpRouteId);
316+
}
317+
assert(
318+
config,
319+
`No warp route config found for warp route ${
320+
readWithFilePath ? args.filePath : args.warpRouteId
321+
}`,
322+
);
275323
return WarpCoreConfigSchema.parse(config);
276324
}
277325

@@ -310,3 +358,43 @@ function createFallbackRoutingConfig(owner: Address): IsmConfig {
310358
owner,
311359
};
312360
}
361+
362+
export async function getWarpRouteDeployConfig({
363+
context,
364+
warpRouteDeployConfigPath,
365+
warpRouteId: providedWarpRouteId,
366+
symbol,
367+
}: {
368+
context: CommandContext;
369+
warpRouteDeployConfigPath?: string;
370+
warpRouteId?: string;
371+
symbol?: string;
372+
}): Promise<WarpRouteDeployConfigMailboxRequired> {
373+
let warpDeployConfig: WarpRouteDeployConfigMailboxRequired;
374+
375+
if (warpRouteDeployConfigPath) {
376+
assert(
377+
isFile(warpRouteDeployConfigPath),
378+
`Warp route deployment config file not found at ${warpRouteDeployConfigPath}`,
379+
);
380+
log(`Using warp route deployment config at ${warpRouteDeployConfigPath}`);
381+
382+
warpDeployConfig = await readWarpRouteDeployConfig({
383+
context,
384+
filePath: warpRouteDeployConfigPath,
385+
});
386+
} else {
387+
const warpRouteId = await useProvidedWarpRouteIdOrPrompt({
388+
warpRouteId: providedWarpRouteId,
389+
context,
390+
symbol,
391+
});
392+
393+
warpDeployConfig = await readWarpRouteDeployConfig({
394+
context,
395+
warpRouteId,
396+
});
397+
}
398+
399+
return warpDeployConfig;
400+
}

typescript/cli/src/context/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import type {
66
ChainMap,
77
ChainMetadata,
88
MultiProvider,
9+
WarpCoreConfig,
10+
WarpRouteDeployConfigMailboxRequired,
911
} from '@hyperlane-xyz/sdk';
1012

1113
export interface ContextSettings {
@@ -35,6 +37,8 @@ export interface WriteCommandContext extends CommandContext {
3537
signer: ethers.Signer;
3638
isDryRun?: boolean;
3739
dryRunChain?: string;
40+
warpDeployConfig?: WarpRouteDeployConfigMailboxRequired;
41+
warpCoreConfig?: WarpCoreConfig;
3842
}
3943

4044
export type CommandModuleWithContext<Args> = CommandModule<

typescript/cli/src/deploy/warp.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,10 @@ export async function runWarpRouteDeploy({
120120
`Using warp route deployment config at ${warpRouteDeploymentConfigPath}`,
121121
);
122122
}
123-
const warpRouteConfig = await readWarpRouteDeployConfig(
124-
warpRouteDeploymentConfigPath,
123+
const warpRouteConfig = await readWarpRouteDeployConfig({
124+
filePath: warpRouteDeploymentConfigPath,
125125
context,
126-
);
126+
});
127127

128128
const chains = Object.keys(warpRouteConfig);
129129

0 commit comments

Comments
 (0)