Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cli): Add hyperlane warp apply #4094

Merged
merged 16 commits into from
Jul 5, 2024
4 changes: 2 additions & 2 deletions typescript/cli/src/commands/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ export const warpDeploymentConfigCommandOption: Options = {
description:
'A path to a JSON or YAML file with a warp route deployment config.',
default: './configs/warp-route-deployment.yaml',
alias: 'w',
alias: 'wd',
};

export const warpCoreConfigCommandOption: Options = {
type: 'string',
description: 'File path to Warp Route config',
alias: 'w',
alias: 'wc',
};

export const agentConfigCommandOption = (
Expand Down
72 changes: 72 additions & 0 deletions typescript/cli/src/commands/warp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
} from '@hyperlane-xyz/core';
import {
ChainMap,
EvmERC20WarpModule,
EvmERC20WarpRouteReader,
TokenStandard,
WarpCoreConfig,
Expand All @@ -18,6 +19,7 @@ import { objMap, promiseObjAll } from '@hyperlane-xyz/utils';
import {
createWarpRouteDeployConfig,
readWarpCoreConfig,
readWarpRouteDeployConfig,
} from '../config/warp.js';
import {
CommandModuleWithContext,
Expand Down Expand Up @@ -50,6 +52,7 @@ export const warpCommand: CommandModule = {
describe: 'Manage Hyperlane warp routes',
builder: (yargs) =>
yargs
.command(apply)
.command(deploy)
.command(init)
.command(read)
Expand All @@ -60,6 +63,75 @@ export const warpCommand: CommandModule = {
handler: () => log('Command required'),
};

export const apply: CommandModuleWithWriteContext<{
config: string;
symbol?: string;
warp: string;
}> = {
command: 'apply',
describe: 'Update Warp Route contracts',
builder: {
paulbalaji marked this conversation as resolved.
Show resolved Hide resolved
config: warpDeploymentConfigCommandOption,
symbol: {
...symbolCommandOption,
demandOption: false,
},
warp: {
...warpCoreConfigCommandOption,
demandOption: true,
},
},
handler: async ({ context, config, symbol, warp }) => {
let warpCoreConfig: WarpCoreConfig;
if (symbol) {
warpCoreConfig = await selectRegistryWarpRoute(context.registry, symbol);
} else if (warp) {
warpCoreConfig = readWarpCoreConfig(warp);
} else {
logRed(`Please specify either a symbol or warp config`);
process.exit(0);
}
// Convert warpCoreConfig.tokens into a mapping of { [chainName]: Config } to allow O(1) reads
const warpCoreReduced = warpCoreConfig.tokens.reduce<
Record<string, WarpCoreConfig['tokens'][number]>
>((o, config) => {
o[config.chainName] = config;
return o;
}, {});

const warpDeployConfig = await readWarpRouteDeployConfig(config);

// Fetch the static Ism factories and attach to WarpDeploy
const addresses = await context.registry.getAddresses();
const updates = await promiseObjAll(
objMap(warpDeployConfig, async (chain, config) => {
config.ismFactoryAddresses = addresses[chain] as any;
const evmERC20WarpModule = new EvmERC20WarpModule(
context.multiProvider,
{
config,
chain,
addresses: {
deployedTokenRoute: warpCoreReduced[chain as any].addressOrDenom!,
},
},
);
return evmERC20WarpModule.update(config);
}),
);

// Loop through each chain, and then loop through each update. ugh.
// @TODO maybe use concurrency for each chain
paulbalaji marked this conversation as resolved.
Show resolved Hide resolved
for (const [chain, transactions] of Object.entries(updates)) {
for (const transaction of transactions) {
await context.multiProvider.sendTransaction(chain, transaction);
}
}

process.exit(0);
},
};

export const deploy: CommandModuleWithWriteContext<{
config: string;
'dry-run': string;
Expand Down
Loading