Skip to content

Commit

Permalink
feat: Options CLI Builder
Browse files Browse the repository at this point in the history
Signed-off-by: Ryan Goulding <goulding@layerzerolabs.org>
  • Loading branch information
ryandgoulding committed Jan 25, 2024
1 parent a48befd commit 2ae50e2
Show file tree
Hide file tree
Showing 17 changed files with 782 additions and 2 deletions.
2 changes: 2 additions & 0 deletions packages/build-lz-options/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dist/
node_modules/
31 changes: 31 additions & 0 deletions packages/build-lz-options/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<p align="center">
<a href="https://layerzero.network">
<img alt="LayerZero" style="max-width: 500px" src="https://d3a2dpnnrypp5h.cloudfront.net/bridge-app/lz.png"/>
</a>
</p>

<h1 align="center">build-lz-oapp</h1>

<!-- The badges section -->
<p align="center">
<!-- Shields.io NPM published package version -->
<a href="https://www.npmjs.com/package/build-lz-oapp"><img alt="NPM Version" src="https://img.shields.io/npm/v/build-lz-oapp"/></a>
<!-- Shields.io NPM downloads -->
<a href="https://www.npmjs.com/package/build-lz-oapp"><img alt="Downloads" src="https://img.shields.io/npm/dm/build-lz-oapp"/></a>
<!-- Shields.io license badge -->
<a href="https://www.npmjs.com/package/build-lz-oapp"><img alt="NPM License" src="https://img.shields.io/npm/l/build-lz-oapp"/></a>
</p>

## Create LayerZero OApp Options <img alt="Static Badge" src="https://img.shields.io/badge/status-work_in_progress-yellow">

The easiest way to get started with LayerZero smart contract development. This CLI tool enables you to quickly start building on top of LayerZero omnichain interoperability protocol. To get started, use the following command:

```bash
npx build-lz-options@latest
# or
yarn build-lz-options
# or
pnpm build-lz-options
# or
bunx build-lz-options
```
3 changes: 3 additions & 0 deletions packages/build-lz-options/cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env node

import('./dist/index.js');
9 changes: 9 additions & 0 deletions packages/build-lz-options/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testTimeout: 15000,
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1',
},
};
61 changes: 61 additions & 0 deletions packages/build-lz-options/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"name": "build-lz-options",
"version": "0.0.1",
"description": "Build LayerZero options with one command",
"keywords": [
"LayerZero",
"OApp",
"Options"
],
"repository": {
"type": "git",
"url": "git+https://github.com/LayerZero-Labs/devtools.git",
"directory": "packages/build-lz-options"
},
"license": "MIT",
"bin": {
"build-lz-options": "./cli.js"
},
"files": [
"cli.js",
"dist"
],
"scripts": {
"prebuild": "tsc -noEmit",
"build": "$npm_execpath tsup",
"clean": "rm -rf dist",
"dev": "$npm_execpath tsup --watch",
"lint": "$npm_execpath eslint '**/*.{js,ts,json}'",
"start": "./cli.js",
"test": "jest"
},
"dependencies": {
"yoga-layout-prebuilt": "^1.10.0"
},
"devDependencies": {
"@layerzerolabs/devtools-evm": "~0.0.2",
"@layerzerolabs/io-devtools": "~0.0.2",
"@layerzerolabs/lz-utility-v2": "~2.0.7",
"@types/jest": "^29.5.11",
"@types/prompts": "^2.4.9",
"@types/react": "^17.0.74",
"commander": "^11.1.0",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"ink": "^3.2.0",
"ink-gradient": "^2.0.0",
"jest": "^29.7.0",
"prompts": "^2.4.2",
"react": "^17.0.2",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.2",
"tsup": "~8.0.1",
"typescript": "^5.3.3"
},
"engines": {
"node": ">=18"
},
"publishConfig": {
"access": "public"
}
}
47 changes: 47 additions & 0 deletions packages/build-lz-options/src/components/config.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from "react";
import { Box, Text } from "ink";
import { OptionType1, OptionConfig, OptionType2 } from "@/types";

interface Props {
value: OptionConfig;
}

interface OptionType1Props {
props: OptionType1;
}

interface OptionType2Props extends OptionType1Props {
props: OptionType2;
}

export const ConfigSummary: React.FC<Props> = ({ value }) => {
return (
<Box flexDirection="column" marginTop={1} marginBottom={1}>
<Text>
Creating LayerZero options <Text bold>{value.type.label}</Text>
</Text>
</Box>
);
};

export const Option1Summary: React.FC<OptionType1Props> = ({ props }) => {
return (
<Box flexDirection="column" marginTop={1} marginBottom={1}>
<Text>
Gas Limit: <Text bold>{props.gasLimit}</Text>
</Text>
</Box>
);
};

export const Option2Summary: React.FC<OptionType2Props> = ({ props }) => {
return (
<Box flexDirection="column" marginTop={1} marginBottom={1}>
<Text>
Gas Limit: <Text bold>{props.gasLimit}</Text>
Native Drop Amount: <Text bold>{props.nativeDropAmount}</Text>
Native Drop Address: <Text bold>{props.nativeDropAddress}</Text>
</Text>
</Box>
);
};
66 changes: 66 additions & 0 deletions packages/build-lz-options/src/components/outputOptions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { makeBytes32 } from "@layerzerolabs/devtools-evm";
import React, { useEffect } from "react";
import type { OptionType1, OptionType2, OptionType3 } from "@/types";
import { Box } from "ink";
import { useTask } from "@/utilities/tasks";
import { optionsType1, optionsType2 } from "@layerzerolabs/lz-utility-v2";

interface Props {
props: OptionType1;
}

export const outputOptionsType1 = async (gasLimit: OptionType1) => {
console.log(optionsType1(gasLimit.gasLimit));
};

export const OutputOptionsType1: React.FC<Props> = ({ props }) => {
const output = useTask(() => outputOptionsType1(props));

useEffect(() => {
output.run().catch(() => {});
}, [output.run]);

return <Box flexDirection="column"></Box>;
};

interface OptionsType2Props {
props: OptionType2;
}

const outputOptionsType2 = async (options: OptionType2) => {
console.log(
optionsType2(
options.gasLimit,
options.nativeDropAmount,
makeBytes32(options.nativeDropAddress),
),
);
};

export const OutputOptionsType2: React.FC<OptionsType2Props> = ({ props }) => {
const output = useTask(() => outputOptionsType2(props));

useEffect(() => {
output.run().catch(() => {});
}, [output.run]);

return <Box flexDirection="column"></Box>;
};

interface OptionsType3Props {
props: OptionType3;
}

const outputOptionsType3 = async (options: OptionType3) => {
console.log(options.output);
};

export const OutputOptionsType3: React.FC<OptionsType3Props> = ({ props }) => {
const output = useTask(() => outputOptionsType3(props));

useEffect(() => {
output.run().catch(() => {});
}, [output.run]);

return <Box flexDirection="column"></Box>;
};
59 changes: 59 additions & 0 deletions packages/build-lz-options/src/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import type { OptionType } from '@/types'
import { ExecutorOptionType, WorkerId } from '@layerzerolabs/lz-utility-v2'

/**
* Supported Option Types.
*/
export const OPTION_TYPES: OptionType[] = [
{
// TODO: use OptionType.TYPE_1 once exported from lz-utility-v2
id: '1',
label: '1: gas for remote execution',
},
{
// TODO: use OptionType.TYPE_2 once exported from lz-utility-v2
id: '2',
label: '2: gas for remote execution and native drop',
},
{
// TODO: use OptionType.TYPE_3 once exported from lz-utility-v2
id: '3',
label: '3: options builder (EndpointV2 only)',
},
]

/**
* Supported Executor Option Types.
*/
export const EXECUTOR_OPTION_TYPE = [
{
id: ExecutorOptionType.LZ_RECEIVE,
label: '1: lzReceive',
},
{
id: ExecutorOptionType.NATIVE_DROP,
label: '2: nativeDrop',
},
{
id: ExecutorOptionType.COMPOSE,
label: '3: compose',
},
{
id: ExecutorOptionType.ORDERED,
label: '4: ordered',
},
]

/**
* Supported Worker Types.
*/
export const WORKER_TYPE = [
{
id: WorkerId.EXECUTOR,
label: '1 Executor',
},
{
id: WorkerId.VERIFIER,
label: '2 Verifier',
},
]
84 changes: 84 additions & 0 deletions packages/build-lz-options/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import React from "react";
import { render } from "ink";
import { Command } from "commander";
import {
promptForOptionType,
promptForOptionType1,
promptForOptionType2,
promptForOptionType3,
} from "@/utilities/prompts";
import {
ConfigSummary,
Option1Summary,
Option2Summary,
} from "@/components/config";
import {
OutputOptionsType1,
OutputOptionsType2,
OutputOptionsType3,
} from "@/components/outputOptions";
import { printLogo } from "@layerzerolabs/io-devtools/swag";

new Command("build-lz-options")
.description("Create LayerZero OApp options with one command")
.action(async () => {
printLogo();

// First we get the config from the user
const config = await promptForOptionType();
render(<ConfigSummary value={config} />).unmount();

switch (config.type.id) {
case "1": {
const options = await promptForOptionType1();
render(
<Option1Summary
props={{
gasLimit: options.gasLimit,
}}
/>,
).unmount();
render(
<OutputOptionsType1
props={{
gasLimit: options.gasLimit,
}}
/>,
);
break;
}
case "2": {
const options = await promptForOptionType2();
render(
<Option2Summary
props={{
gasLimit: options.gasLimit,
nativeDropAmount: options.nativeDropAmount,
nativeDropAddress: options.nativeDropAddress,
}}
/>,
).unmount();
render(
<OutputOptionsType2
props={{
gasLimit: options.gasLimit,
nativeDropAmount: options.nativeDropAmount,
nativeDropAddress: options.nativeDropAddress,
}}
/>,
);
break;
}
case "3": {
const options = await promptForOptionType3();
render(
<OutputOptionsType3
props={{
output: options.toHex(),
}}
/>,
);
}
}
})
.parseAsync();
21 changes: 21 additions & 0 deletions packages/build-lz-options/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export interface OptionConfig {
type: OptionType
}

export interface OptionType {
id: string
label: string
}

export interface OptionType1 {
gasLimit: string
}

export interface OptionType2 extends OptionType1 {
nativeDropAmount: string
nativeDropAddress: string
}

export interface OptionType3 {
output: string
}
Loading

0 comments on commit 2ae50e2

Please sign in to comment.