Sealevel chains should always use hex keys for relayers (#2402)

### Description

This PR adds support for protocol-type awareness in infra.

A new field `type` is added to chainMetadata. This field is inspected
during key creation and relayer helm chart creation. Relayer keys for
sealevel chains are set explicitly to always be hex keys.

### Drive-by changes

None
### Related issues

- https://github.com/hyperlane-xyz/hyperlane-monorepo/issues/2350

### Backward compatibility

_Are these changes backward compatible?_

Yes
pull/2407/head
Asa Oines 1 year ago committed by GitHub
parent 4bf065548c
commit e317c6c85d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      typescript/infra/src/agents/key-utils.ts
  2. 37
      typescript/infra/src/config/agent/relayer.ts
  3. 10
      typescript/sdk/src/agents/types.ts
  4. 7
      typescript/sdk/src/consts/chainMetadata.test.ts
  5. 29
      typescript/sdk/src/consts/chainMetadata.ts
  6. 1
      typescript/sdk/src/index.ts

@ -1,4 +1,4 @@
import { ChainName } from '@hyperlane-xyz/sdk';
import { ChainName, ProtocolType, chainMetadata } from '@hyperlane-xyz/sdk';
import { Contexts } from '../../config/contexts';
import {
@ -25,8 +25,14 @@ export function getCloudAgentKey(
chainName?: ChainName,
index?: number,
): CloudAgentKey {
if (agentConfig.aws && role !== Role.Deployer) {
// The deployer is always GCP-based
let isAws = !!agentConfig.aws;
// The deployer is always GCP-based
isAws = isAws && role !== Role.Deployer;
const isSealevel =
!!chainName && chainMetadata[chainName].protocol === ProtocolType.Sealevel;
// Sealevel chains should use GCP-based hex keys for relayers
isAws = isAws && !(isSealevel && role == Role.Relayer);
if (isAws) {
return new AgentAwsKey(agentConfig, role, chainName, index);
} else {
return new AgentGCPKey(

@ -1,6 +1,6 @@
import { BigNumberish } from 'ethers';
import { ChainMap, chainMetadata } from '@hyperlane-xyz/sdk';
import { ChainMap, ProtocolType, chainMetadata } from '@hyperlane-xyz/sdk';
import { AgentAwsUser } from '../../agents/aws';
import { Role } from '../../roles';
@ -125,22 +125,31 @@ export class RelayerConfigHelper extends AgentConfigHelper<RelayerConfig> {
// Get the signer configuration for each chain by the chain name.
async signers(): Promise<ChainMap<KeyConfig>> {
if (!this.aws)
if (this.aws) {
const awsUser = new AgentAwsUser(
this.runEnv,
this.context,
Role.Relayer,
this.aws.region,
);
await awsUser.createIfNotExists();
const awsKey = (await awsUser.createKeyIfNotExists(this)).keyConfig;
return Object.fromEntries(
this.contextChainNames.map((name) => {
const chain = chainMetadata[name];
// Sealevel chains always use hex keys
if (chain?.protocol == ProtocolType.Sealevel) {
return [name, { type: KeyType.Hex }];
} else {
return [name, awsKey];
}
}),
);
} else {
return Object.fromEntries(
this.contextChainNames.map((name) => [name, { type: KeyType.Hex }]),
);
const awsUser = new AgentAwsUser(
this.runEnv,
this.context,
Role.Relayer,
this.aws.region,
);
await awsUser.createIfNotExists();
const key = (await awsUser.createKeyIfNotExists(this)).keyConfig;
return Object.fromEntries(
this.contextChainNames.map((name) => [name, key]),
);
}
}
// Returns whether the relayer requires AWS credentials

@ -1,5 +1,6 @@
import { types } from '@hyperlane-xyz/utils';
import { ProtocolType } from '../consts/chainMetadata';
import { MultiProvider } from '../providers/MultiProvider';
import { ChainMap, ChainName } from '../types';
@ -30,18 +31,13 @@ export interface HyperlaneAgentAddresses {
validatorAnnounce: types.Address;
}
export enum AgentProtocol {
Ethereum = 'ethereum',
Fuel = 'fuel',
}
export interface AgentChainSetupBase {
name: ChainName;
domain: number;
signer?: AgentSigner;
finalityBlocks: number;
addresses: HyperlaneAgentAddresses;
protocol: AgentProtocol;
protocol: ProtocolType;
connection?: AgentConnection;
index?: { from: number };
}
@ -79,7 +75,7 @@ export function buildAgentConfig(
interchainGasPaymaster: addresses[chain].interchainGasPaymaster,
validatorAnnounce: addresses[chain].validatorAnnounce,
},
protocol: AgentProtocol.Ethereum,
protocol: metadata.protocol,
finalityBlocks: metadata.blocks?.reorgPeriod ?? 1,
};

@ -1,10 +1,15 @@
import { expect } from 'chai';
import { ChainMetadata, isValidChainMetadata } from './chainMetadata';
import {
ChainMetadata,
ProtocolType,
isValidChainMetadata,
} from './chainMetadata';
const minimalSchema: ChainMetadata = {
chainId: 5,
name: 'goerli',
protocol: ProtocolType.Ethereum,
publicRpcUrls: [{ http: 'https://foobar.com' }],
};

@ -17,6 +17,12 @@ export enum ExplorerFamily {
Other = 'other',
}
export enum ProtocolType {
Ethereum = 'ethereum',
Sealevel = 'sealevel',
Fuel = 'fuel',
}
export type ExplorerFamilyType = `${ExplorerFamily}`;
/**
@ -28,6 +34,7 @@ export interface ChainMetadata {
/** Hyperlane domain, only required if differs from id above */
domainId?: number;
name: ChainName;
protocol: ProtocolType;
/** Human-readable name */
displayName?: string;
/** Shorter human-readable name */
@ -91,6 +98,7 @@ export const ChainMetadataSchema = z.object({
chainId: z.number().positive(),
domainId: z.number().positive().optional(),
name: z.string(),
protocol: z.string(),
displayName: z.string().optional(),
displayNameShort: z.string().optional(),
nativeToken: z
@ -174,6 +182,7 @@ export const xDaiToken = { name: 'xDai', symbol: 'xDai', decimals: 18 };
export const alfajores: ChainMetadata = {
chainId: 44787,
name: Chains.alfajores,
protocol: ProtocolType.Ethereum,
displayName: 'Alfajores',
nativeToken: celoToken,
publicRpcUrls: [{ http: 'https://alfajores-forno.celo-testnet.org' }],
@ -202,6 +211,7 @@ export const alfajores: ChainMetadata = {
export const arbitrum: ChainMetadata = {
chainId: 42161,
name: Chains.arbitrum,
protocol: ProtocolType.Ethereum,
displayName: 'Arbitrum',
nativeToken: etherToken,
publicRpcUrls: [{ http: 'https://arb1.arbitrum.io/rpc' }],
@ -226,6 +236,7 @@ export const arbitrum: ChainMetadata = {
export const arbitrumgoerli: ChainMetadata = {
chainId: 421613,
name: Chains.arbitrumgoerli,
protocol: ProtocolType.Ethereum,
displayName: 'Arbitrum Goerli',
displayNameShort: 'Arb. Goerli',
nativeToken: etherToken,
@ -249,6 +260,7 @@ export const arbitrumgoerli: ChainMetadata = {
export const avalanche: ChainMetadata = {
chainId: 43114,
name: Chains.avalanche,
protocol: ProtocolType.Ethereum,
displayName: 'Avalanche',
nativeToken: avaxToken,
publicRpcUrls: [
@ -281,6 +293,7 @@ export const avalanche: ChainMetadata = {
export const bsc: ChainMetadata = {
chainId: 56,
name: Chains.bsc,
protocol: ProtocolType.Ethereum,
displayName: 'Binance Smart Chain',
displayNameShort: 'Binance',
nativeToken: bnbToken,
@ -308,6 +321,7 @@ export const bsc: ChainMetadata = {
export const bsctestnet: ChainMetadata = {
chainId: 97,
name: Chains.bsctestnet,
protocol: ProtocolType.Ethereum,
displayName: 'BSC Testnet',
nativeToken: bnbToken,
publicRpcUrls: [{ http: 'https://data-seed-prebsc-1-s3.binance.org:8545' }],
@ -330,6 +344,7 @@ export const bsctestnet: ChainMetadata = {
export const celo: ChainMetadata = {
chainId: 42220,
name: Chains.celo,
protocol: ProtocolType.Ethereum,
displayName: 'Celo',
nativeToken: celoToken,
publicRpcUrls: [{ http: 'https://forno.celo.org' }],
@ -359,6 +374,7 @@ export const celo: ChainMetadata = {
export const ethereum: ChainMetadata = {
chainId: 1,
name: Chains.ethereum,
protocol: ProtocolType.Ethereum,
displayName: 'Ethereum',
nativeToken: etherToken,
publicRpcUrls: [
@ -390,6 +406,7 @@ export const ethereum: ChainMetadata = {
export const fuji: ChainMetadata = {
chainId: 43113,
name: Chains.fuji,
protocol: ProtocolType.Ethereum,
displayName: 'Fuji',
nativeToken: avaxToken,
publicRpcUrls: [
@ -417,6 +434,7 @@ export const fuji: ChainMetadata = {
export const goerli: ChainMetadata = {
chainId: 5,
name: Chains.goerli,
protocol: ProtocolType.Ethereum,
displayName: 'Goerli',
nativeToken: etherToken,
publicRpcUrls: [
@ -443,6 +461,7 @@ export const goerli: ChainMetadata = {
export const sepolia: ChainMetadata = {
chainId: 11155111,
name: Chains.sepolia,
protocol: ProtocolType.Ethereum,
displayName: 'Sepolia',
nativeToken: etherToken,
publicRpcUrls: [
@ -468,6 +487,7 @@ export const sepolia: ChainMetadata = {
export const moonbasealpha: ChainMetadata = {
chainId: 1287,
name: Chains.moonbasealpha,
protocol: ProtocolType.Ethereum,
displayName: 'Moonbase Alpha',
displayNameShort: 'Moonbase',
nativeToken: {
@ -495,6 +515,7 @@ export const moonbasealpha: ChainMetadata = {
export const moonbeam: ChainMetadata = {
chainId: 1284,
name: Chains.moonbeam,
protocol: ProtocolType.Ethereum,
displayName: 'Moonbeam',
nativeToken: {
decimals: 18,
@ -522,6 +543,7 @@ export const moonbeam: ChainMetadata = {
export const mumbai: ChainMetadata = {
chainId: 80001,
name: Chains.mumbai,
protocol: ProtocolType.Ethereum,
displayName: 'Mumbai',
nativeToken: maticToken,
publicRpcUrls: [
@ -556,6 +578,7 @@ export const mumbai: ChainMetadata = {
export const optimism: ChainMetadata = {
chainId: 10,
name: Chains.optimism,
protocol: ProtocolType.Ethereum,
displayName: 'Optimism',
nativeToken: etherToken,
publicRpcUrls: [{ http: 'https://mainnet.optimism.io' }],
@ -580,6 +603,7 @@ export const optimism: ChainMetadata = {
export const optimismgoerli: ChainMetadata = {
chainId: 420,
name: Chains.optimismgoerli,
protocol: ProtocolType.Ethereum,
displayName: 'Optimism Goerli',
displayNameShort: 'Opt. Goerli',
nativeToken: etherToken,
@ -603,6 +627,7 @@ export const optimismgoerli: ChainMetadata = {
export const polygon: ChainMetadata = {
chainId: 137,
name: Chains.polygon,
protocol: ProtocolType.Ethereum,
displayName: 'Polygon',
nativeToken: etherToken,
publicRpcUrls: [
@ -637,6 +662,7 @@ export const polygon: ChainMetadata = {
export const gnosis: ChainMetadata = {
chainId: 100,
name: Chains.gnosis,
protocol: ProtocolType.Ethereum,
displayName: 'Gnosis',
nativeToken: xDaiToken,
publicRpcUrls: [
@ -668,6 +694,7 @@ export const gnosis: ChainMetadata = {
export const test1: ChainMetadata = {
chainId: 13371,
name: Chains.test1,
protocol: ProtocolType.Ethereum,
displayName: 'Test 1',
nativeToken: etherToken,
publicRpcUrls: [{ http: 'http://localhost:8545' }],
@ -683,6 +710,7 @@ export const test1: ChainMetadata = {
export const test2: ChainMetadata = {
chainId: 13372,
name: Chains.test2,
protocol: ProtocolType.Ethereum,
displayName: 'Test 2',
nativeToken: etherToken,
publicRpcUrls: [{ http: 'http://localhost:8545' }],
@ -698,6 +726,7 @@ export const test2: ChainMetadata = {
export const test3: ChainMetadata = {
chainId: 13373,
name: Chains.test3,
protocol: ProtocolType.Ethereum,
displayName: 'Test 3',
nativeToken: etherToken,
publicRpcUrls: [{ http: 'http://localhost:8545' }],

@ -13,6 +13,7 @@ export {
ChainMetadataSchema,
ExplorerFamily,
ExplorerFamilyType,
ProtocolType,
RpcPaginationOptions,
chainIdToMetadata,
chainMetadata,

Loading…
Cancel
Save