Skip to content

Commit

Permalink
chore: Stub of OApp wire task
Browse files Browse the repository at this point in the history
  • Loading branch information
janjakubnanista committed Dec 8, 2023
1 parent db08c00 commit 35d2aa4
Show file tree
Hide file tree
Showing 9 changed files with 213 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const { EndpointId } = require('@layerzerolabs/lz-definitions');

module.exports = {
contracts: [
{
eid: EndpointId.EON_MAINNET,
contractName: 'DefaultOApp',
},
{
eid: 'Invalid EndpointId',
contractName: 'DefaultOApp',
},
],
};
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
contracts: [],
connections: [],
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`task/oapp/wire with invalid configs should fail with a malformed JS file (001) 1`] = `
[Error: Config from file '/app/packages/ua-utils-evm-hardhat-test/test/task/oapp/__data__/configs/invalid.config.001.js' is malformed. Please fix the following errors:
contracts:
- Property 'contracts.0.contract': Invalid input
- Property 'contracts.1.contract': Invalid input,
connections:
- Property 'connections': Required]
`;

exports[`task/oapp/wire with invalid configs should fail with an empty JS file 1`] = `
[Error: Config from file '/app/packages/ua-utils-evm-hardhat-test/test/task/oapp/__data__/configs/invalid.config.empty.js' is malformed. Please fix the following errors:
contracts:
- Property 'contracts': Required,
connections:
- Property 'connections': Required]
`;

exports[`task/oapp/wire with invalid configs should fail with an empty JSON file 1`] = `[Error: Unable to read config file '/app/packages/ua-utils-evm-hardhat-test/test/task/oapp/__data__/configs/invalid.config.empty.json': SyntaxError: Unexpected end of JSON input]`;
107 changes: 107 additions & 0 deletions packages/ua-utils-evm-hardhat-test/test/task/oapp/wire.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { setupDefaultEndpoint } from '../../__utils__/endpoint'
import hre from 'hardhat'
import { isFile, promptToContinue } from '@layerzerolabs/io-utils'
import { resolve } from 'path'
import { TASK_LZ_WIRE_OAPP } from '@layerzerolabs/ua-utils-evm-hardhat'

jest.mock('@layerzerolabs/io-utils', () => {
const original = jest.requireActual('@layerzerolabs/io-utils')

return {
...original,
promptToContinue: jest.fn().mockRejectedValue('Not mocked'),
}
})

const promptToContinueMock = promptToContinue as jest.Mock

describe('task/oapp/wire', () => {
const CONFIGS_BASE_DIR = resolve(__dirname, '__data__', 'configs')
const configPathFixture = (fileName: string): string => {
const path = resolve(CONFIGS_BASE_DIR, fileName)

expect(isFile(path)).toBeTruthy()

return path
}

beforeEach(async () => {
promptToContinueMock.mockReset()

await setupDefaultEndpoint()
})

describe('with invalid configs', () => {
it('should fail if the config file does not exist', async () => {
await expect(hre.run(TASK_LZ_WIRE_OAPP, { oappConfig: './does-not-exist.js' })).rejects.toThrow(
/Unable to read config file/
)
})

it('should fail if the config file is not a file', async () => {
await expect(hre.run(TASK_LZ_WIRE_OAPP, { oappConfig: __dirname })).rejects.toThrow(
/Unable to read config file/
)
})

it('should fail if the config file is not a valid JSON or JS file', async () => {
const readme = resolve(__dirname, '..', '..', '..', 'README.md')

expect(isFile(readme)).toBeTruthy()

await expect(hre.run(TASK_LZ_WIRE_OAPP, { oappConfig: readme })).rejects.toThrow(
/Unable to read config file/
)
})

it('should fail with an empty JSON file', async () => {
const oappConfig = configPathFixture('invalid.config.empty.json')

await expect(hre.run(TASK_LZ_WIRE_OAPP, { oappConfig })).rejects.toMatchSnapshot()
})

it('should fail with an empty JS file', async () => {
const oappConfig = configPathFixture('invalid.config.empty.js')

await expect(hre.run(TASK_LZ_WIRE_OAPP, { oappConfig })).rejects.toMatchSnapshot()
})

it('should fail with a malformed JS file (001)', async () => {
const oappConfig = configPathFixture('invalid.config.001.js')

await expect(hre.run(TASK_LZ_WIRE_OAPP, { oappConfig })).rejects.toMatchSnapshot()
})
})

describe('with valid configs', () => {
it('should ask the user whether they want to continue', async () => {
const oappConfig = configPathFixture('valid.config.empty.js')

promptToContinueMock.mockResolvedValue(true)

await hre.run(TASK_LZ_WIRE_OAPP, { oappConfig })

expect(promptToContinueMock).toHaveBeenCalledTimes(1)
})

it('should return undefined if the user decides not to continue', async () => {
const oappConfig = configPathFixture('valid.config.empty.js')

promptToContinueMock.mockResolvedValue(false)

const result = await hre.run(TASK_LZ_WIRE_OAPP, { oappConfig })

expect(result).toBeUndefined()
})

it('should return a list of transactions if the user decides to continue', async () => {
const oappConfig = configPathFixture('valid.config.empty.js')

promptToContinueMock.mockResolvedValue(true)

const result = await hre.run(TASK_LZ_WIRE_OAPP, { oappConfig })

expect(result).toEqual([])
})
})
})
1 change: 1 addition & 0 deletions packages/ua-utils-evm-hardhat/src/tasks/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
import './oapp'
import './getDefaultConfig'
1 change: 1 addition & 0 deletions packages/ua-utils-evm-hardhat/src/tasks/oapp/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import './wire'
62 changes: 62 additions & 0 deletions packages/ua-utils-evm-hardhat/src/tasks/oapp/wire.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { task, types } from 'hardhat/config'
import type { ActionType } from 'hardhat/types'
import { TASK_LZ_WIRE_OAPP } from '@/constants/tasks'
import { isFile, isReadable, promptToContinue } from '@layerzerolabs/io-utils'
import { OAppOmniGraphHardhat, OAppOmniGraphHardhatSchema } from '@/oapp'

interface TaskArgs {
oappConfig: string
}

const action: ActionType<TaskArgs> = async ({ oappConfig: oappConfigPath }) => {
// First we check that the config file is indeed there and we can read it
const isConfigReadable = isFile(oappConfigPath) && isReadable(oappConfigPath)
if (!isConfigReadable) {
throw new Error(
`Unable to read config file '${oappConfigPath}'. Check that the file exists and is readable to your terminal user`
)
}

// Now let's see if we can load the config file
let rawConfig: unknown
try {
rawConfig = require(oappConfigPath)
} catch (error) {
throw new Error(`Unable to read config file '${oappConfigPath}': ${error}`)
}

// It's time to make sure that the config is not malformed
//
// At this stage we are only interested in the shape of the data,
// we are not checking whether the information makes sense (e.g.
// whether there are no missing nodes etc)
const configParseResult = OAppOmniGraphHardhatSchema.safeParse(rawConfig)
if (configParseResult.success === false) {
// FIXME Error formatting
const errors = configParseResult.error.flatten(
(issue) => `Property '${issue.path.join('.') ?? '[root]'}': ${issue.message}`
)
const formErrors = errors.formErrors.map((error) => `- ${error}`).join(`\n`)
const fieldErrors = Object.entries(errors.fieldErrors).map(
([field, errors]) => `\n${field}:\n${errors.map((error) => `- ${error}`).join(`\n`)}`
)
const allErrors = [...formErrors, fieldErrors]

throw new Error(
`Config from file '${oappConfigPath}' is malformed. Please fix the following errors:\n\n${allErrors}`
)
}

// At this point we have a correctly typed config
const config: OAppOmniGraphHardhat = configParseResult.data

const go = await promptToContinue()
if (!go) {
return undefined
}

return []
}
task(TASK_LZ_WIRE_OAPP, 'Wire LayerZero OApp')
.addParam('oappConfig', 'Path to your LayerZero OApp config', './layerzero.config.js', types.string)
.setAction(action)

0 comments on commit 35d2aa4

Please sign in to comment.