Skip to content

Commit f66dcc8

Browse files
feat: add ISM compatibility validation for core and warp route deployments
1 parent bae1979 commit f66dcc8

File tree

2 files changed

+59
-13
lines changed

2 files changed

+59
-13
lines changed

typescript/cli/src/deploy/core.ts

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ export async function runCoreDeploy(params: DeployParams) {
6363
'Select chain to connect:',
6464
);
6565
}
66+
67+
// Validate ISM compatibility
68+
validateIsmCompatibility(chain, config, context);
69+
6670
let apiKeys: ChainMap<string> = {};
6771
if (!skipConfirmation)
6872
apiKeys = await requestAndSaveApiKeys([chain], chainMetadata, registry);
@@ -84,19 +88,6 @@ export async function runCoreDeploy(params: DeployParams) {
8488

8589
const userAddress = await signer.getAddress();
8690

87-
const { technicalStack: chainTechnicalStack } =
88-
context.multiProvider.getChainMetadata(chain);
89-
90-
if (typeof config.defaultIsm !== 'string') {
91-
assert(
92-
isIsmCompatible({
93-
chainTechnicalStack,
94-
ismType: config.defaultIsm?.type,
95-
}),
96-
`ERROR: Selected ISM of type ${config.defaultIsm?.type} is not compatible with the selected Chain Technical Stack of ${chainTechnicalStack}!`,
97-
);
98-
}
99-
10091
const initialBalances = await prepareDeploy(context, userAddress, [chain]);
10192

10293
const contractVerifier = new ContractVerifier(
@@ -128,6 +119,29 @@ export async function runCoreDeploy(params: DeployParams) {
128119
log(indentYamlOrJson(yamlStringify(deployedAddresses, null, 2), 4));
129120
}
130121

122+
/**
123+
* Validates that the ISM configuration is compatible with the chain's technical stack.
124+
* Throws an error if an incompatible ISM type is configured.
125+
*/
126+
function validateIsmCompatibility(
127+
chain: ChainName,
128+
config: CoreConfig,
129+
context: WriteCommandContext,
130+
) {
131+
const { technicalStack: chainTechnicalStack } =
132+
context.multiProvider.getChainMetadata(chain);
133+
134+
if (typeof config.defaultIsm !== 'string') {
135+
assert(
136+
isIsmCompatible({
137+
chainTechnicalStack,
138+
ismType: config.defaultIsm?.type,
139+
}),
140+
`Selected ISM of type ${config.defaultIsm?.type} is not compatible with the selected Chain Technical Stack of ${chainTechnicalStack} for chain ${chain}!`,
141+
);
142+
}
143+
}
144+
131145
export async function runCoreApply(params: ApplyParams) {
132146
const { context, chain, deployedCoreAddresses, config } = params;
133147
const { multiProvider } = context;

typescript/cli/src/deploy/warp.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import {
5151
getTokenConnectionId,
5252
hypERC20factories,
5353
isCollateralTokenConfig,
54+
isIsmCompatible,
5455
isTokenMetadata,
5556
} from '@hyperlane-xyz/sdk';
5657
import {
@@ -127,6 +128,9 @@ export async function runWarpRouteDeploy({
127128

128129
const chains = Object.keys(warpRouteConfig);
129130

131+
// Validate ISM compatibility for all chains
132+
validateIsmCompatibility(warpRouteConfig, context);
133+
130134
let apiKeys: ChainMap<string> = {};
131135
if (!skipConfirmation)
132136
apiKeys = await requestAndSaveApiKeys(chains, chainMetadata, registry);
@@ -176,6 +180,34 @@ async function runDeployPlanStep({ context, warpDeployConfig }: DeployParams) {
176180
if (!isConfirmed) throw new Error('Deployment cancelled');
177181
}
178182

183+
/**
184+
* Validates that the ISM configurations are compatible with each chain's technical stack.
185+
* Throws an error if an incompatible ISM type is configured for a chain.
186+
*/
187+
function validateIsmCompatibility(
188+
warpRouteConfig: WarpRouteDeployConfig,
189+
context: WriteCommandContext,
190+
) {
191+
for (const chain of Object.keys(warpRouteConfig)) {
192+
const config = warpRouteConfig[chain];
193+
const { technicalStack: chainTechnicalStack } =
194+
context.multiProvider.getChainMetadata(chain);
195+
196+
if (
197+
config.interchainSecurityModule &&
198+
typeof config.interchainSecurityModule !== 'string'
199+
) {
200+
assert(
201+
isIsmCompatible({
202+
chainTechnicalStack,
203+
ismType: config.interchainSecurityModule.type,
204+
}),
205+
`Selected ISM of type ${config.interchainSecurityModule.type} is not compatible with the selected Chain Technical Stack of ${chainTechnicalStack} for chain ${chain}!`,
206+
);
207+
}
208+
}
209+
}
210+
179211
async function executeDeploy(
180212
params: DeployParams,
181213
apiKeys: ChainMap<string>,

0 commit comments

Comments
 (0)