chore: Upgrade to ESlint 9 and forbid import cycles (#4897)
### Description - Upgrade from eslint 8 -> 9 - Forbid import cycles and self imports - Fix lint errors caught by v9 but not v8 - Include utils package in CI linting **No semantic changes, just some shuffling of things around to avoid cycles** Fixes https://github.com/hyperlane-xyz/hyperlane-monorepo/issues/4898 https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-cycle.md https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-self-import.mdpull/4824/merge
parent
d51815760b
commit
fa6d5f5c63
@ -0,0 +1,5 @@ |
|||||||
|
--- |
||||||
|
'@hyperlane-xyz/utils': minor |
||||||
|
--- |
||||||
|
|
||||||
|
Add toUpperCamelCase and deepFind functionss |
@ -0,0 +1,5 @@ |
|||||||
|
--- |
||||||
|
'@hyperlane-xyz/sdk': minor |
||||||
|
--- |
||||||
|
|
||||||
|
Add decodeIsmMetadata function |
@ -1,4 +0,0 @@ |
|||||||
node_modules |
|
||||||
dist |
|
||||||
coverage |
|
||||||
*.cts |
|
@ -1,65 +0,0 @@ |
|||||||
{ |
|
||||||
"env": { |
|
||||||
"node": true, |
|
||||||
"browser": true, |
|
||||||
"es2021": true |
|
||||||
}, |
|
||||||
"root": true, |
|
||||||
"parser": "@typescript-eslint/parser", |
|
||||||
"parserOptions": { |
|
||||||
"ecmaVersion": 12, |
|
||||||
"sourceType": "module", |
|
||||||
"project": "./tsconfig.json" |
|
||||||
}, |
|
||||||
"plugins": ["@typescript-eslint","jest"], |
|
||||||
"extends": [ |
|
||||||
"eslint:recommended", |
|
||||||
"plugin:@typescript-eslint/recommended", |
|
||||||
"prettier" |
|
||||||
], |
|
||||||
"rules": { |
|
||||||
"no-console": ["error"], |
|
||||||
"no-eval": ["error"], |
|
||||||
"no-extra-boolean-cast": ["error"], |
|
||||||
"no-ex-assign": ["error"], |
|
||||||
"no-constant-condition": ["off"], |
|
||||||
"no-return-await": ["error"], |
|
||||||
"no-restricted-imports": ["error", { |
|
||||||
"name": "console", |
|
||||||
"message": "Please use a logger and/or the utils' package assert" |
|
||||||
}, { |
|
||||||
"name": "fs", |
|
||||||
"message": "Avoid use of node-specific libraries" |
|
||||||
}], |
|
||||||
"guard-for-in": ["error"], |
|
||||||
"@typescript-eslint/ban-ts-comment": ["off"], |
|
||||||
"@typescript-eslint/explicit-module-boundary-types": ["off"], |
|
||||||
"@typescript-eslint/no-explicit-any": ["off"], |
|
||||||
"@typescript-eslint/no-floating-promises": ["error"], |
|
||||||
"@typescript-eslint/no-non-null-assertion": ["off"], |
|
||||||
"@typescript-eslint/no-require-imports": ["warn"], |
|
||||||
"@typescript-eslint/no-unused-vars": [ |
|
||||||
"error", |
|
||||||
{ |
|
||||||
"argsIgnorePattern": "^_", |
|
||||||
"varsIgnorePattern": "^_", |
|
||||||
"caughtErrorsIgnorePattern": "^_" |
|
||||||
} |
|
||||||
], |
|
||||||
"@typescript-eslint/ban-types": [ |
|
||||||
"error", |
|
||||||
{ |
|
||||||
"types": { |
|
||||||
// Unban the {} type which is a useful shorthand for non-nullish value |
|
||||||
"{}": false |
|
||||||
}, |
|
||||||
"extendDefaults": true |
|
||||||
} |
|
||||||
], |
|
||||||
"jest/no-disabled-tests": "warn", |
|
||||||
"jest/no-focused-tests": "error", |
|
||||||
"jest/no-identical-title": "error", |
|
||||||
"jest/prefer-to-have-length": "warn", |
|
||||||
"jest/valid-expect": "error" |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,115 @@ |
|||||||
|
import { FlatCompat } from '@eslint/eslintrc'; |
||||||
|
import js from '@eslint/js'; |
||||||
|
import typescriptEslint from '@typescript-eslint/eslint-plugin'; |
||||||
|
import tsParser from '@typescript-eslint/parser'; |
||||||
|
import importPlugin from 'eslint-plugin-import'; |
||||||
|
import jest from 'eslint-plugin-jest'; |
||||||
|
import globals from 'globals'; |
||||||
|
import path from 'node:path'; |
||||||
|
import { fileURLToPath } from 'node:url'; |
||||||
|
|
||||||
|
const __filename = fileURLToPath(import.meta.url); |
||||||
|
const __dirname = path.dirname(__filename); |
||||||
|
export const compat = new FlatCompat({ |
||||||
|
baseDirectory: __dirname, |
||||||
|
recommendedConfig: js.configs.recommended, |
||||||
|
allConfig: js.configs.all, |
||||||
|
}); |
||||||
|
|
||||||
|
export default [ |
||||||
|
{ |
||||||
|
ignores: [ |
||||||
|
'**/node_modules', |
||||||
|
'**/dist', |
||||||
|
'**/coverage', |
||||||
|
'**/*.cjs', |
||||||
|
'**/*.cts', |
||||||
|
'**/*.mjs', |
||||||
|
'jest.config.js', |
||||||
|
], |
||||||
|
}, |
||||||
|
...compat.extends( |
||||||
|
'eslint:recommended', |
||||||
|
'plugin:import/recommended', |
||||||
|
'plugin:import/typescript', |
||||||
|
'plugin:@typescript-eslint/recommended', |
||||||
|
'prettier', |
||||||
|
), |
||||||
|
{ |
||||||
|
plugins: { |
||||||
|
import: importPlugin, |
||||||
|
'@typescript-eslint': typescriptEslint, |
||||||
|
jest, |
||||||
|
}, |
||||||
|
|
||||||
|
languageOptions: { |
||||||
|
globals: { |
||||||
|
...globals.node, |
||||||
|
...globals.browser, |
||||||
|
}, |
||||||
|
|
||||||
|
parser: tsParser, |
||||||
|
ecmaVersion: 12, |
||||||
|
sourceType: 'module', |
||||||
|
|
||||||
|
parserOptions: { |
||||||
|
project: './tsconfig.json', |
||||||
|
}, |
||||||
|
}, |
||||||
|
|
||||||
|
settings: { |
||||||
|
'import/resolver': { |
||||||
|
typescript: true, |
||||||
|
node: true, |
||||||
|
}, |
||||||
|
}, |
||||||
|
|
||||||
|
rules: { |
||||||
|
'guard-for-in': ['error'], |
||||||
|
'import/no-cycle': ['error'], |
||||||
|
'import/no-self-import': ['error'], |
||||||
|
'import/no-named-as-default-member': ['off'], |
||||||
|
'no-console': ['error'], |
||||||
|
'no-eval': ['error'], |
||||||
|
'no-extra-boolean-cast': ['error'], |
||||||
|
'no-ex-assign': ['error'], |
||||||
|
'no-constant-condition': ['off'], |
||||||
|
'no-return-await': ['error'], |
||||||
|
|
||||||
|
'no-restricted-imports': [ |
||||||
|
'error', |
||||||
|
{ |
||||||
|
name: 'console', |
||||||
|
message: 'Please use a logger and/or the utils package assert', |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'fs', |
||||||
|
message: 'Avoid use of node-specific libraries', |
||||||
|
}, |
||||||
|
], |
||||||
|
|
||||||
|
'@typescript-eslint/ban-ts-comment': ['off'], |
||||||
|
'@typescript-eslint/explicit-module-boundary-types': ['off'], |
||||||
|
'@typescript-eslint/no-explicit-any': ['off'], |
||||||
|
'@typescript-eslint/no-floating-promises': ['error'], |
||||||
|
'@typescript-eslint/no-non-null-assertion': ['off'], |
||||||
|
'@typescript-eslint/no-require-imports': ['warn'], |
||||||
|
'@typescript-eslint/no-unused-expressions': ['off'], |
||||||
|
'@typescript-eslint/no-empty-object-type': ['off'], |
||||||
|
'@typescript-eslint/no-unused-vars': [ |
||||||
|
'error', |
||||||
|
{ |
||||||
|
argsIgnorePattern: '^_', |
||||||
|
varsIgnorePattern: '^_', |
||||||
|
caughtErrorsIgnorePattern: '^_', |
||||||
|
}, |
||||||
|
], |
||||||
|
|
||||||
|
'jest/no-disabled-tests': 'warn', |
||||||
|
'jest/no-focused-tests': 'error', |
||||||
|
'jest/no-identical-title': 'error', |
||||||
|
'jest/prefer-to-have-length': 'warn', |
||||||
|
'jest/valid-expect': 'error', |
||||||
|
}, |
||||||
|
}, |
||||||
|
]; |
@ -1,6 +0,0 @@ |
|||||||
{ |
|
||||||
"rules": { |
|
||||||
"no-console": ["off"] |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
@ -0,0 +1,17 @@ |
|||||||
|
import MonorepoDefaults from '../../eslint.config.mjs'; |
||||||
|
|
||||||
|
export default [ |
||||||
|
...MonorepoDefaults, |
||||||
|
{ |
||||||
|
files: ['./src/**/*.ts'], |
||||||
|
}, |
||||||
|
{ |
||||||
|
rules: { |
||||||
|
'no-console': ['off'], |
||||||
|
'no-restricted-imports': ['off'], |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
ignores: ['**/__mocks__/*','**/tests/*',] |
||||||
|
} |
||||||
|
]; |
@ -0,0 +1,9 @@ |
|||||||
|
{ |
||||||
|
"extends": "../tsconfig.json", |
||||||
|
"compilerOptions": { |
||||||
|
"outDir": "./dist/", |
||||||
|
"rootDir": "./src" |
||||||
|
}, |
||||||
|
"exclude": ["./node_modules/", "./dist/"], |
||||||
|
"include": ["./src/*.ts"] |
||||||
|
} |
@ -1,2 +0,0 @@ |
|||||||
node_modules |
|
||||||
dist |
|
@ -1,6 +0,0 @@ |
|||||||
{ |
|
||||||
"rules": { |
|
||||||
"no-console": ["off"], |
|
||||||
"no-restricted-imports": ["off"] |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,20 @@ |
|||||||
|
import MonorepoDefaults from '../../eslint.config.mjs'; |
||||||
|
|
||||||
|
export default [ |
||||||
|
...MonorepoDefaults, |
||||||
|
{ |
||||||
|
files: ['./src/**/*.ts', './cli.ts', './env.ts'], |
||||||
|
}, |
||||||
|
{ |
||||||
|
rules: { |
||||||
|
'no-console': ['off'], |
||||||
|
'no-restricted-imports': ['off'], |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
ignores: ['./src/tests/**/*.ts'], |
||||||
|
rules: { |
||||||
|
'import/no-cycle': ['off'], |
||||||
|
}, |
||||||
|
}, |
||||||
|
]; |
@ -0,0 +1,35 @@ |
|||||||
|
import { WarpCoreConfig } from '@hyperlane-xyz/sdk'; |
||||||
|
|
||||||
|
import { readWarpCoreConfig } from '../config/warp.js'; |
||||||
|
import { CommandContext } from '../context/types.js'; |
||||||
|
import { logRed } from '../logger.js'; |
||||||
|
|
||||||
|
import { selectRegistryWarpRoute } from './tokens.js'; |
||||||
|
|
||||||
|
/** |
||||||
|
* Gets a {@link WarpCoreConfig} based on the provided path or prompts the user to choose one: |
||||||
|
* - if `symbol` is provided the user will have to select one of the available warp routes. |
||||||
|
* - if `warp` is provided the config will be read by the provided file path. |
||||||
|
* - if none is provided the CLI will exit. |
||||||
|
*/ |
||||||
|
export async function getWarpCoreConfigOrExit({ |
||||||
|
context, |
||||||
|
symbol, |
||||||
|
warp, |
||||||
|
}: { |
||||||
|
context: CommandContext; |
||||||
|
symbol?: string; |
||||||
|
warp?: string; |
||||||
|
}): Promise<WarpCoreConfig> { |
||||||
|
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); |
||||||
|
} |
||||||
|
|
||||||
|
return warpCoreConfig; |
||||||
|
} |
@ -1,5 +0,0 @@ |
|||||||
node_modules |
|
||||||
dist |
|
||||||
coverage |
|
||||||
src/types |
|
||||||
hardhat.config.ts |
|
@ -1,39 +0,0 @@ |
|||||||
{ |
|
||||||
"env": { |
|
||||||
"node": true, |
|
||||||
"browser": true, |
|
||||||
"es2021": true |
|
||||||
}, |
|
||||||
"root": true, |
|
||||||
"parser": "@typescript-eslint/parser", |
|
||||||
"parserOptions": { |
|
||||||
"ecmaVersion": 12, |
|
||||||
"sourceType": "module", |
|
||||||
"project": "./tsconfig.json" |
|
||||||
}, |
|
||||||
"plugins": ["@typescript-eslint"], |
|
||||||
"extends": [ |
|
||||||
"eslint:recommended", |
|
||||||
"plugin:@typescript-eslint/recommended", |
|
||||||
"prettier" |
|
||||||
], |
|
||||||
"rules": { |
|
||||||
"no-eval": ["error"], |
|
||||||
"no-ex-assign": ["error"], |
|
||||||
"no-constant-condition": ["off"], |
|
||||||
"@typescript-eslint/ban-ts-comment": ["off"], |
|
||||||
"@typescript-eslint/explicit-module-boundary-types": ["off"], |
|
||||||
"@typescript-eslint/no-explicit-any": ["off"], |
|
||||||
"@typescript-eslint/no-floating-promises": ["error"], |
|
||||||
"@typescript-eslint/no-non-null-assertion": ["off"], |
|
||||||
"@typescript-eslint/no-require-imports": ["warn"], |
|
||||||
"@typescript-eslint/no-unused-vars": [ |
|
||||||
"error", |
|
||||||
{ |
|
||||||
"argsIgnorePattern": "^_", |
|
||||||
"varsIgnorePattern": "^_", |
|
||||||
"caughtErrorsIgnorePattern": "^_" |
|
||||||
} |
|
||||||
] |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,17 @@ |
|||||||
|
import MonorepoDefaults from '../../eslint.config.mjs'; |
||||||
|
|
||||||
|
export default [ |
||||||
|
...MonorepoDefaults, |
||||||
|
{ |
||||||
|
files: ['./src/**/*.ts'], |
||||||
|
}, |
||||||
|
{ |
||||||
|
ignores: ["**/src/types/*"], |
||||||
|
}, |
||||||
|
{ |
||||||
|
ignores: ['./src/scripts'], |
||||||
|
rules: { |
||||||
|
'no-console': ['off'], |
||||||
|
}, |
||||||
|
}, |
||||||
|
]; |
@ -1,7 +0,0 @@ |
|||||||
{ |
|
||||||
"rules": { |
|
||||||
"@typescript-eslint/explicit-module-boundary-types": ["warn", { |
|
||||||
"allowArgumentsExplicitlyTypedAsAny": true |
|
||||||
}] |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,25 @@ |
|||||||
|
import MonorepoDefaults from '../../eslint.config.mjs'; |
||||||
|
|
||||||
|
export default [ |
||||||
|
...MonorepoDefaults, |
||||||
|
{ |
||||||
|
files: ['./src/**/*.ts'], |
||||||
|
rules: { |
||||||
|
'@typescript-eslint/explicit-module-boundary-types': [ |
||||||
|
'warn', |
||||||
|
{ |
||||||
|
allowArgumentsExplicitlyTypedAsAny: true, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
ignores: ['./src/ism/metadata/**/*.ts'], |
||||||
|
rules: { |
||||||
|
'import/no-cycle': ['off'], |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
ignores: ['src/**/*.js'], |
||||||
|
}, |
||||||
|
]; |
@ -1,5 +0,0 @@ |
|||||||
{ |
|
||||||
"rules": { |
|
||||||
"sort-keys": ["error"] |
|
||||||
} |
|
||||||
} |
|
@ -1,5 +0,0 @@ |
|||||||
{ |
|
||||||
"rules": { |
|
||||||
"no-console": ["off"] |
|
||||||
} |
|
||||||
} |
|
@ -1,96 +0,0 @@ |
|||||||
import { z } from 'zod'; |
|
||||||
|
|
||||||
import { StorageGasOracleConfigSchema } from '../gas/oracle/types.js'; |
|
||||||
import { ZHash } from '../metadata/customZodTypes.js'; |
|
||||||
import { OwnableSchema, PausableSchema } from '../schemas.js'; |
|
||||||
|
|
||||||
import { |
|
||||||
AggregationHookConfig, |
|
||||||
DomainRoutingHookConfig, |
|
||||||
FallbackRoutingHookConfig, |
|
||||||
HookType, |
|
||||||
} from './types.js'; |
|
||||||
|
|
||||||
export const ProtocolFeeSchema = OwnableSchema.extend({ |
|
||||||
type: z.literal(HookType.PROTOCOL_FEE), |
|
||||||
beneficiary: z.string(), |
|
||||||
maxProtocolFee: z.string(), |
|
||||||
protocolFee: z.string(), |
|
||||||
}); |
|
||||||
|
|
||||||
export const MerkleTreeSchema = z.object({ |
|
||||||
type: z.literal(HookType.MERKLE_TREE), |
|
||||||
}); |
|
||||||
|
|
||||||
export const PausableHookSchema = PausableSchema.extend({ |
|
||||||
type: z.literal(HookType.PAUSABLE), |
|
||||||
}); |
|
||||||
|
|
||||||
export const OpStackHookSchema = OwnableSchema.extend({ |
|
||||||
type: z.literal(HookType.OP_STACK), |
|
||||||
nativeBridge: z.string(), |
|
||||||
destinationChain: z.string(), |
|
||||||
}); |
|
||||||
|
|
||||||
export const ArbL2ToL1HookSchema = z.object({ |
|
||||||
type: z.literal(HookType.ARB_L2_TO_L1), |
|
||||||
arbSys: z |
|
||||||
.string() |
|
||||||
.describe( |
|
||||||
'precompile for sending messages to L1, interface here: https://github.com/OffchainLabs/nitro-contracts/blob/90037b996509312ef1addb3f9352457b8a99d6a6/src/precompiles/ArbSys.sol#L12', |
|
||||||
), |
|
||||||
bridge: z |
|
||||||
.string() |
|
||||||
.optional() |
|
||||||
.describe( |
|
||||||
'address of the bridge contract on L1, optional only needed for non @arbitrum/sdk chains', |
|
||||||
), |
|
||||||
destinationChain: z.string(), |
|
||||||
childHook: z.lazy((): z.ZodSchema => HookConfigSchema), |
|
||||||
}); |
|
||||||
|
|
||||||
export const IgpSchema = OwnableSchema.extend({ |
|
||||||
type: z.literal(HookType.INTERCHAIN_GAS_PAYMASTER), |
|
||||||
beneficiary: z.string(), |
|
||||||
oracleKey: z.string(), |
|
||||||
overhead: z.record(z.number()), |
|
||||||
oracleConfig: z.record(StorageGasOracleConfigSchema), |
|
||||||
}); |
|
||||||
|
|
||||||
export const DomainRoutingHookConfigSchema: z.ZodSchema<DomainRoutingHookConfig> = |
|
||||||
z.lazy(() => |
|
||||||
OwnableSchema.extend({ |
|
||||||
type: z.literal(HookType.ROUTING), |
|
||||||
domains: z.record(HookConfigSchema), |
|
||||||
}), |
|
||||||
); |
|
||||||
|
|
||||||
export const FallbackRoutingHookConfigSchema: z.ZodSchema<FallbackRoutingHookConfig> = |
|
||||||
z.lazy(() => |
|
||||||
OwnableSchema.extend({ |
|
||||||
type: z.literal(HookType.FALLBACK_ROUTING), |
|
||||||
domains: z.record(HookConfigSchema), |
|
||||||
fallback: HookConfigSchema, |
|
||||||
}), |
|
||||||
); |
|
||||||
|
|
||||||
export const AggregationHookConfigSchema: z.ZodSchema<AggregationHookConfig> = |
|
||||||
z.lazy(() => |
|
||||||
z.object({ |
|
||||||
type: z.literal(HookType.AGGREGATION), |
|
||||||
hooks: z.array(HookConfigSchema), |
|
||||||
}), |
|
||||||
); |
|
||||||
|
|
||||||
export const HookConfigSchema = z.union([ |
|
||||||
ZHash, |
|
||||||
ProtocolFeeSchema, |
|
||||||
PausableHookSchema, |
|
||||||
OpStackHookSchema, |
|
||||||
MerkleTreeSchema, |
|
||||||
IgpSchema, |
|
||||||
DomainRoutingHookConfigSchema, |
|
||||||
FallbackRoutingHookConfigSchema, |
|
||||||
AggregationHookConfigSchema, |
|
||||||
ArbL2ToL1HookSchema, |
|
||||||
]); |
|
@ -0,0 +1,41 @@ |
|||||||
|
import { IsmType } from '../types.js'; |
||||||
|
|
||||||
|
import { AggregationMetadataBuilder } from './aggregation.js'; |
||||||
|
import { ArbL2ToL1MetadataBuilder } from './arbL2ToL1.js'; |
||||||
|
import { MultisigMetadataBuilder } from './multisig.js'; |
||||||
|
import { NullMetadataBuilder } from './null.js'; |
||||||
|
import { DefaultFallbackRoutingMetadataBuilder } from './routing.js'; |
||||||
|
import { MetadataContext, StructuredMetadata } from './types.js'; |
||||||
|
|
||||||
|
export function decodeIsmMetadata( |
||||||
|
metadata: string, |
||||||
|
context: MetadataContext, |
||||||
|
): StructuredMetadata { |
||||||
|
const { ism } = context; |
||||||
|
switch (ism.type) { |
||||||
|
case IsmType.TRUSTED_RELAYER: |
||||||
|
return NullMetadataBuilder.decode(ism); |
||||||
|
|
||||||
|
case IsmType.MERKLE_ROOT_MULTISIG: |
||||||
|
case IsmType.MESSAGE_ID_MULTISIG: |
||||||
|
return MultisigMetadataBuilder.decode(metadata, ism.type); |
||||||
|
|
||||||
|
case IsmType.AGGREGATION: |
||||||
|
return AggregationMetadataBuilder.decode(metadata, { ...context, ism }); |
||||||
|
|
||||||
|
case IsmType.ROUTING: |
||||||
|
return DefaultFallbackRoutingMetadataBuilder.decode(metadata, { |
||||||
|
...context, |
||||||
|
ism, |
||||||
|
}); |
||||||
|
|
||||||
|
case IsmType.ARB_L2_TO_L1: |
||||||
|
return ArbL2ToL1MetadataBuilder.decode(metadata, { |
||||||
|
...context, |
||||||
|
ism, |
||||||
|
}); |
||||||
|
|
||||||
|
default: |
||||||
|
throw new Error(`Unsupported ISM type: ${ism.type}`); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
import type { providers } from 'ethers'; |
||||||
|
|
||||||
|
import type { DispatchedMessage } from '../../core/types.js'; |
||||||
|
import type { DerivedHookConfig } from '../../hook/EvmHookReader.js'; |
||||||
|
import type { DerivedIsmConfig } from '../EvmIsmReader.js'; |
||||||
|
|
||||||
|
import type { AggregationMetadata } from './aggregation.js'; |
||||||
|
import type { ArbL2ToL1Metadata } from './arbL2ToL1.js'; |
||||||
|
import type { MultisigMetadata } from './multisig.js'; |
||||||
|
import type { NullMetadata } from './null.js'; |
||||||
|
import type { RoutingMetadata } from './routing.js'; |
||||||
|
|
||||||
|
export type StructuredMetadata = |
||||||
|
| NullMetadata |
||||||
|
| MultisigMetadata |
||||||
|
| ArbL2ToL1Metadata |
||||||
|
| AggregationMetadata<any> |
||||||
|
| RoutingMetadata<any>; |
||||||
|
|
||||||
|
export interface MetadataContext< |
||||||
|
IsmContext = DerivedIsmConfig, |
||||||
|
HookContext = DerivedHookConfig, |
||||||
|
> { |
||||||
|
message: DispatchedMessage; |
||||||
|
dispatchTx: providers.TransactionReceipt; |
||||||
|
ism: IsmContext; |
||||||
|
hook: HookContext; |
||||||
|
} |
||||||
|
|
||||||
|
export interface MetadataBuilder { |
||||||
|
build(context: MetadataContext): Promise<string>; |
||||||
|
} |
@ -1,103 +0,0 @@ |
|||||||
import { z } from 'zod'; |
|
||||||
|
|
||||||
import { ZHash } from '../metadata/customZodTypes.js'; |
|
||||||
import { OwnableSchema, PausableSchema } from '../schemas.js'; |
|
||||||
|
|
||||||
import { AggregationIsmConfig, IsmType, RoutingIsmConfig } from './types.js'; |
|
||||||
|
|
||||||
const ValidatorInfoSchema = z.object({ |
|
||||||
signingAddress: ZHash, |
|
||||||
weight: z.number(), |
|
||||||
}); |
|
||||||
|
|
||||||
export const TestIsmConfigSchema = z.object({ |
|
||||||
type: z.literal(IsmType.TEST_ISM), |
|
||||||
}); |
|
||||||
|
|
||||||
export const MultisigConfigSchema = z.object({ |
|
||||||
validators: z.array(ZHash), |
|
||||||
threshold: z.number(), |
|
||||||
}); |
|
||||||
|
|
||||||
export const WeightedMultisigConfigSchema = z.object({ |
|
||||||
validators: z.array(ValidatorInfoSchema), |
|
||||||
thresholdWeight: z.number(), |
|
||||||
}); |
|
||||||
|
|
||||||
export const TrustedRelayerIsmConfigSchema = z.object({ |
|
||||||
type: z.literal(IsmType.TRUSTED_RELAYER), |
|
||||||
relayer: z.string(), |
|
||||||
}); |
|
||||||
|
|
||||||
export const OpStackIsmConfigSchema = z.object({ |
|
||||||
type: z.literal(IsmType.OP_STACK), |
|
||||||
origin: z.string(), |
|
||||||
nativeBridge: z.string(), |
|
||||||
}); |
|
||||||
|
|
||||||
export const ArbL2ToL1IsmConfigSchema = z.object({ |
|
||||||
type: z.literal(IsmType.ARB_L2_TO_L1), |
|
||||||
bridge: z.string(), |
|
||||||
}); |
|
||||||
|
|
||||||
export const PausableIsmConfigSchema = PausableSchema.and( |
|
||||||
z.object({ |
|
||||||
type: z.literal(IsmType.PAUSABLE), |
|
||||||
}), |
|
||||||
); |
|
||||||
|
|
||||||
export const MultisigIsmConfigSchema = MultisigConfigSchema.and( |
|
||||||
z.object({ |
|
||||||
type: z.union([ |
|
||||||
z.literal(IsmType.MERKLE_ROOT_MULTISIG), |
|
||||||
z.literal(IsmType.MESSAGE_ID_MULTISIG), |
|
||||||
z.literal(IsmType.STORAGE_MERKLE_ROOT_MULTISIG), |
|
||||||
z.literal(IsmType.STORAGE_MESSAGE_ID_MULTISIG), |
|
||||||
]), |
|
||||||
}), |
|
||||||
); |
|
||||||
|
|
||||||
export const WeightedMultisigIsmConfigSchema = WeightedMultisigConfigSchema.and( |
|
||||||
z.object({ |
|
||||||
type: z.union([ |
|
||||||
z.literal(IsmType.WEIGHTED_MERKLE_ROOT_MULTISIG), |
|
||||||
z.literal(IsmType.WEIGHTED_MESSAGE_ID_MULTISIG), |
|
||||||
]), |
|
||||||
}), |
|
||||||
); |
|
||||||
|
|
||||||
export const RoutingIsmConfigSchema: z.ZodSchema<RoutingIsmConfig> = z.lazy( |
|
||||||
() => |
|
||||||
OwnableSchema.extend({ |
|
||||||
type: z.union([ |
|
||||||
z.literal(IsmType.ROUTING), |
|
||||||
z.literal(IsmType.FALLBACK_ROUTING), |
|
||||||
]), |
|
||||||
domains: z.record(IsmConfigSchema), |
|
||||||
}), |
|
||||||
); |
|
||||||
|
|
||||||
export const AggregationIsmConfigSchema: z.ZodSchema<AggregationIsmConfig> = z |
|
||||||
.lazy(() => |
|
||||||
z.object({ |
|
||||||
type: z.literal(IsmType.AGGREGATION), |
|
||||||
modules: z.array(IsmConfigSchema), |
|
||||||
threshold: z.number(), |
|
||||||
}), |
|
||||||
) |
|
||||||
.refine((data) => data.threshold <= data.modules.length, { |
|
||||||
message: 'Threshold must be less than or equal to the number of modules', |
|
||||||
}); |
|
||||||
|
|
||||||
export const IsmConfigSchema = z.union([ |
|
||||||
ZHash, |
|
||||||
TestIsmConfigSchema, |
|
||||||
OpStackIsmConfigSchema, |
|
||||||
PausableIsmConfigSchema, |
|
||||||
TrustedRelayerIsmConfigSchema, |
|
||||||
MultisigIsmConfigSchema, |
|
||||||
WeightedMultisigIsmConfigSchema, |
|
||||||
RoutingIsmConfigSchema, |
|
||||||
AggregationIsmConfigSchema, |
|
||||||
ArbL2ToL1IsmConfigSchema, |
|
||||||
]); |
|
@ -1,8 +1,7 @@ |
|||||||
import { expect } from 'chai'; |
import { expect } from 'chai'; |
||||||
import { ethers } from 'ethers'; |
import { ethers } from 'ethers'; |
||||||
|
|
||||||
import { AggregationIsmConfigSchema } from './schemas.js'; |
import { AggregationIsmConfigSchema, IsmType } from './types.js'; |
||||||
import { IsmType } from './types.js'; |
|
||||||
|
|
||||||
const SOME_ADDRESS = ethers.Wallet.createRandom().address; |
const SOME_ADDRESS = ethers.Wallet.createRandom().address; |
||||||
describe('AggregationIsmConfigSchema refine', () => { |
describe('AggregationIsmConfigSchema refine', () => { |
@ -1,5 +0,0 @@ |
|||||||
{ |
|
||||||
"rules": { |
|
||||||
"no-console": ["off"] |
|
||||||
} |
|
||||||
} |
|
@ -1,43 +0,0 @@ |
|||||||
import { z } from 'zod'; |
|
||||||
|
|
||||||
import { HookConfigSchema } from '../hook/schemas.js'; |
|
||||||
import { IsmConfigSchema } from '../ism/schemas.js'; |
|
||||||
import { ZHash } from '../metadata/customZodTypes.js'; |
|
||||||
import { DeployedOwnableSchema, OwnableSchema } from '../schemas.js'; |
|
||||||
|
|
||||||
export const MailboxClientConfigSchema = OwnableSchema.extend({ |
|
||||||
mailbox: ZHash, |
|
||||||
hook: HookConfigSchema.optional(), |
|
||||||
interchainSecurityModule: IsmConfigSchema.optional(), |
|
||||||
}); |
|
||||||
|
|
||||||
export const ForeignDeploymentConfigSchema = z.object({ |
|
||||||
foreignDeployment: z.string().optional(), |
|
||||||
}); |
|
||||||
|
|
||||||
const RemoteRouterDomain = z.string(); |
|
||||||
const RemoteRouterRouter = z.string().startsWith('0x'); |
|
||||||
export const RemoteRoutersSchema = z.record( |
|
||||||
RemoteRouterDomain, |
|
||||||
RemoteRouterRouter, |
|
||||||
); |
|
||||||
|
|
||||||
export const RouterConfigSchema = MailboxClientConfigSchema.merge( |
|
||||||
ForeignDeploymentConfigSchema, |
|
||||||
).merge( |
|
||||||
z.object({ |
|
||||||
remoteRouters: RemoteRoutersSchema.optional(), |
|
||||||
proxyAdmin: DeployedOwnableSchema.optional(), |
|
||||||
}), |
|
||||||
); |
|
||||||
|
|
||||||
const DestinationGasDomain = z.string(); |
|
||||||
const DestinationGasAmount = z.string(); // This must be a string type to match Ether's type
|
|
||||||
export const DestinationGasSchema = z.record( |
|
||||||
DestinationGasDomain, |
|
||||||
DestinationGasAmount, |
|
||||||
); |
|
||||||
export const GasRouterConfigSchema = RouterConfigSchema.extend({ |
|
||||||
gas: z.number().optional(), |
|
||||||
destinationGas: DestinationGasSchema.optional(), |
|
||||||
}); |
|
@ -1,5 +0,0 @@ |
|||||||
{ |
|
||||||
"rules": { |
|
||||||
"@typescript-eslint/explicit-module-boundary-types": ["off"] |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,3 @@ |
|||||||
|
import MonorepoDefaults from '../../eslint.config.mjs'; |
||||||
|
|
||||||
|
export default [...MonorepoDefaults, { files: ['./src/**/*.ts'] }]; |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue