From 3e88d2615e1aed8f08543d4cf513b972f008577f Mon Sep 17 00:00:00 2001
From: sirarthurmoney <95722332+sirarthurmoney@users.noreply.github.com>
Date: Fri, 19 Jul 2024 07:10:52 -0700
Subject: [PATCH] =?UTF-8?q?=F0=9F=97=9E=EF=B8=8F=20Adding=20in=20OFTAdapte?=
=?UTF-8?q?r=20to=20create-lz-oapp=20(#713)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.changeset/forty-monkeys-vanish.md | 6 +
examples/oft-adapter/.env.example | 15 +
examples/oft-adapter/.eslintignore | 10 +
examples/oft-adapter/.eslintrc.js | 10 +
examples/oft-adapter/.gitignore | 24 +
examples/oft-adapter/.nvmrc | 1 +
examples/oft-adapter/.prettierignore | 10 +
examples/oft-adapter/.prettierrc.js | 3 +
examples/oft-adapter/README.md | 120 +++++
examples/oft-adapter/contracts/MyOFT.sol | 14 +
.../oft-adapter/contracts/MyOFTAdapter.sol | 24 +
.../contracts/mocks/MyERC20Mock.sol | 13 +
.../contracts/mocks/MyOFTAdapterMock.sol | 9 +
.../oft-adapter/contracts/mocks/MyOFTMock.sol | 19 +
examples/oft-adapter/deploy/MyOFT.ts | 60 +++
examples/oft-adapter/deploy/MyOFTAdapter.ts | 60 +++
examples/oft-adapter/foundry.toml | 27 +
examples/oft-adapter/hardhat.config.ts | 83 +++
examples/oft-adapter/layerzero.config.ts | 75 +++
examples/oft-adapter/package.json | 76 +++
examples/oft-adapter/solhint.config.js | 1 +
.../test/foundry/MyOFTAdapter.t.sol | 180 +++++++
.../test/hardhat/MyOFTAdapter.test.ts | 117 +++++
examples/oft-adapter/test/mocks/ERC20Mock.sol | 12 +
.../oft-adapter/test/mocks/OFTAdapterMock.sol | 38 ++
.../test/mocks/OFTComposerMock.sol | 27 +
examples/oft-adapter/test/mocks/OFTMock.sol | 59 +++
examples/oft-adapter/tsconfig.json | 13 +
examples/oft-adapter/type-extensions.ts | 23 +
packages/create-lz-oapp/src/config.ts | 7 +
pnpm-lock.yaml | 476 +++++++++++++++---
tests-user/tests/create-lz-oapp.bats | 33 ++
32 files changed, 1580 insertions(+), 65 deletions(-)
create mode 100644 .changeset/forty-monkeys-vanish.md
create mode 100644 examples/oft-adapter/.env.example
create mode 100644 examples/oft-adapter/.eslintignore
create mode 100644 examples/oft-adapter/.eslintrc.js
create mode 100644 examples/oft-adapter/.gitignore
create mode 100644 examples/oft-adapter/.nvmrc
create mode 100644 examples/oft-adapter/.prettierignore
create mode 100644 examples/oft-adapter/.prettierrc.js
create mode 100644 examples/oft-adapter/README.md
create mode 100644 examples/oft-adapter/contracts/MyOFT.sol
create mode 100644 examples/oft-adapter/contracts/MyOFTAdapter.sol
create mode 100644 examples/oft-adapter/contracts/mocks/MyERC20Mock.sol
create mode 100644 examples/oft-adapter/contracts/mocks/MyOFTAdapterMock.sol
create mode 100644 examples/oft-adapter/contracts/mocks/MyOFTMock.sol
create mode 100644 examples/oft-adapter/deploy/MyOFT.ts
create mode 100644 examples/oft-adapter/deploy/MyOFTAdapter.ts
create mode 100644 examples/oft-adapter/foundry.toml
create mode 100644 examples/oft-adapter/hardhat.config.ts
create mode 100644 examples/oft-adapter/layerzero.config.ts
create mode 100644 examples/oft-adapter/package.json
create mode 100644 examples/oft-adapter/solhint.config.js
create mode 100644 examples/oft-adapter/test/foundry/MyOFTAdapter.t.sol
create mode 100644 examples/oft-adapter/test/hardhat/MyOFTAdapter.test.ts
create mode 100644 examples/oft-adapter/test/mocks/ERC20Mock.sol
create mode 100644 examples/oft-adapter/test/mocks/OFTAdapterMock.sol
create mode 100644 examples/oft-adapter/test/mocks/OFTComposerMock.sol
create mode 100644 examples/oft-adapter/test/mocks/OFTMock.sol
create mode 100644 examples/oft-adapter/tsconfig.json
create mode 100644 examples/oft-adapter/type-extensions.ts
diff --git a/.changeset/forty-monkeys-vanish.md b/.changeset/forty-monkeys-vanish.md
new file mode 100644
index 000000000..9d9e08813
--- /dev/null
+++ b/.changeset/forty-monkeys-vanish.md
@@ -0,0 +1,6 @@
+---
+"create-lz-oapp": patch
+"@layerzerolabs/oft-adapter-example": patch
+---
+
+Adding in OFTAdapter to create-lz-oapp
diff --git a/examples/oft-adapter/.env.example b/examples/oft-adapter/.env.example
new file mode 100644
index 000000000..197ba1d67
--- /dev/null
+++ b/examples/oft-adapter/.env.example
@@ -0,0 +1,15 @@
+# .-.-. .-.-. .-.-. .-.-. .-.-. .-.-. .-.-. .-.-
+# / / \ \ / / \ \ / / \ \ / / \ \ / / \ \ / / \ \ / / \ \ / / \
+# `-' `-`-' `-`-' `-`-' `-`-' `-`-' `-`-' `-`-'
+#
+# Example environment configuration
+#
+# .-.-. .-.-. .-.-. .-.-. .-.-. .-.-. .-.-. .-.-
+# / / \ \ / / \ \ / / \ \ / / \ \ / / \ \ / / \ \ / / \ \ / / \
+# `-' `-`-' `-`-' `-`-' `-`-' `-`-' `-`-' `-`-'
+
+# By default, the examples support both mnemonic-based and private key-based authentication
+#
+# You don't need to set both of these values, just pick the one that you prefer and set that one
+MNEMONIC=
+PRIVATE_KEY=
\ No newline at end of file
diff --git a/examples/oft-adapter/.eslintignore b/examples/oft-adapter/.eslintignore
new file mode 100644
index 000000000..ee9f768fd
--- /dev/null
+++ b/examples/oft-adapter/.eslintignore
@@ -0,0 +1,10 @@
+artifacts
+cache
+dist
+node_modules
+out
+*.log
+*.sol
+*.yaml
+*.lock
+package-lock.json
\ No newline at end of file
diff --git a/examples/oft-adapter/.eslintrc.js b/examples/oft-adapter/.eslintrc.js
new file mode 100644
index 000000000..f0ea891fd
--- /dev/null
+++ b/examples/oft-adapter/.eslintrc.js
@@ -0,0 +1,10 @@
+require('@rushstack/eslint-patch/modern-module-resolution');
+
+module.exports = {
+ extends: ['@layerzerolabs/eslint-config-next/recommended'],
+ rules: {
+ // @layerzerolabs/eslint-config-next defines rules for turborepo-based projects
+ // that are not relevant for this particular project
+ 'turbo/no-undeclared-env-vars': 'off',
+ },
+};
diff --git a/examples/oft-adapter/.gitignore b/examples/oft-adapter/.gitignore
new file mode 100644
index 000000000..e2face954
--- /dev/null
+++ b/examples/oft-adapter/.gitignore
@@ -0,0 +1,24 @@
+node_modules
+.env
+coverage
+coverage.json
+typechain
+typechain-types
+
+# Hardhat files
+cache
+artifacts
+
+
+# LayerZero specific files
+.layerzero
+
+# foundry test compilation files
+out
+
+# pnpm
+pnpm-error.log
+
+# Editor and OS files
+.DS_Store
+.idea
diff --git a/examples/oft-adapter/.nvmrc b/examples/oft-adapter/.nvmrc
new file mode 100644
index 000000000..b714151ef
--- /dev/null
+++ b/examples/oft-adapter/.nvmrc
@@ -0,0 +1 @@
+v18.18.0
\ No newline at end of file
diff --git a/examples/oft-adapter/.prettierignore b/examples/oft-adapter/.prettierignore
new file mode 100644
index 000000000..6e8232f5a
--- /dev/null
+++ b/examples/oft-adapter/.prettierignore
@@ -0,0 +1,10 @@
+artifacts/
+cache/
+dist/
+node_modules/
+out/
+*.log
+*ignore
+*.yaml
+*.lock
+package-lock.json
\ No newline at end of file
diff --git a/examples/oft-adapter/.prettierrc.js b/examples/oft-adapter/.prettierrc.js
new file mode 100644
index 000000000..6f55b4019
--- /dev/null
+++ b/examples/oft-adapter/.prettierrc.js
@@ -0,0 +1,3 @@
+module.exports = {
+ ...require('@layerzerolabs/prettier-config-next'),
+};
diff --git a/examples/oft-adapter/README.md b/examples/oft-adapter/README.md
new file mode 100644
index 000000000..6d2d4b72d
--- /dev/null
+++ b/examples/oft-adapter/README.md
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+ Homepage | Docs | Developers
+
+
+OFTAdapter Example
+
+
+ Quickstart | Configuration | Message Execution Options | Endpoint Addresses
+
+
+Template project for getting started with LayerZero's OFTAdapter
contract development.
+
+### OFTAdapter additional setup:
+
+- In your `hardhat.config.ts` file, add the following configuration to the network you want to deploy the OFTAdapter to:
+ ```typescript
+ // Replace `0x0` with the address of the ERC20 token you want to adapt to the OFT functionality.
+ oftAdapter: {
+ tokenAddress: '0x0',
+ }
+ ```
+
+## 1) Developing Contracts
+
+#### Installing dependencies
+
+We recommend using `pnpm` as a package manager (but you can of course use a package manager of your choice):
+
+```bash
+pnpm install
+```
+
+#### Compiling your contracts
+
+This project supports both `hardhat` and `forge` compilation. By default, the `compile` command will execute both:
+
+```bash
+pnpm compile
+```
+
+If you prefer one over the other, you can use the tooling-specific commands:
+
+```bash
+pnpm compile:forge
+pnpm compile:hardhat
+```
+
+Or adjust the `package.json` to for example remove `forge` build:
+
+```diff
+- "compile": "$npm_execpath run compile:forge && $npm_execpath run compile:hardhat",
+- "compile:forge": "forge build",
+- "compile:hardhat": "hardhat compile",
++ "compile": "hardhat compile"
+```
+
+#### Running tests
+
+Similarly to the contract compilation, we support both `hardhat` and `forge` tests. By default, the `test` command will execute both:
+
+```bash
+pnpm test
+```
+
+If you prefer one over the other, you can use the tooling-specific commands:
+
+```bash
+pnpm test:forge
+pnpm test:hardhat
+```
+
+Or adjust the `package.json` to for example remove `hardhat` tests:
+
+```diff
+- "test": "$npm_execpath test:forge && $npm_execpath test:hardhat",
+- "test:forge": "forge test",
+- "test:hardhat": "$npm_execpath hardhat test"
++ "test": "forge test"
+```
+
+## 2) Deploying Contracts
+
+Set up deployer wallet/account:
+
+- Rename `.env.example` -> `.env`
+- Choose your preferred means of setting up your deployer wallet/account:
+
+```
+MNEMONIC="test test test test test test test test test test test junk"
+or...
+PRIVATE_KEY="0xabc...def"
+```
+
+- Fund this address with the corresponding chain's native tokens you want to deploy to.
+
+To deploy your contracts to your desired blockchains, run the following command in your project's folder:
+
+```bash
+npx hardhat lz:deploy
+```
+
+More information about available CLI arguments can be found using the `--help` flag:
+
+```bash
+npx hardhat lz:deploy --help
+```
+
+By following these steps, you can focus more on creating innovative omnichain solutions and less on the complexities of cross-chain communication.
+
+
+
+
+ Join our community on Discord | Follow us on Twitter
+
diff --git a/examples/oft-adapter/contracts/MyOFT.sol b/examples/oft-adapter/contracts/MyOFT.sol
new file mode 100644
index 000000000..f8bc7b47f
--- /dev/null
+++ b/examples/oft-adapter/contracts/MyOFT.sol
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: UNLICENSED
+pragma solidity ^0.8.22;
+
+import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
+import { OFT } from "@layerzerolabs/oft-evm/contracts/OFT.sol";
+
+contract MyOFT is OFT {
+ constructor(
+ string memory _name,
+ string memory _symbol,
+ address _lzEndpoint,
+ address _delegate
+ ) OFT(_name, _symbol, _lzEndpoint, _delegate) Ownable(_delegate) {}
+}
diff --git a/examples/oft-adapter/contracts/MyOFTAdapter.sol b/examples/oft-adapter/contracts/MyOFTAdapter.sol
new file mode 100644
index 000000000..f87f5e511
--- /dev/null
+++ b/examples/oft-adapter/contracts/MyOFTAdapter.sol
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: UNLICENSED
+pragma solidity ^0.8.22;
+
+import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
+import { OFTAdapter } from "@layerzerolabs/oft-evm/contracts/OFTAdapter.sol";
+
+/**
+ * @title OFTAdapter Contract
+ * @dev OFTAdapter is a contract that adapts an ERC-20 token to the OFT functionality.
+ *
+ * @dev For existing ERC20 tokens, this can be used to convert the token to crosschain compatibility.
+ * @dev WARNING: ONLY 1 of these should exist for a given global mesh,
+ * unless you make a NON-default implementation of OFT and needs to be done very carefully.
+ * @dev WARNING: The default OFTAdapter implementation assumes LOSSLESS transfers, ie. 1 token in, 1 token out.
+ * IF the 'innerToken' applies something like a transfer fee, the default will NOT work...
+ * a pre/post balance check will need to be done to calculate the amountSentLD/amountReceivedLD.
+ */
+contract MyOFTAdapter is OFTAdapter {
+ constructor(
+ address _token,
+ address _lzEndpoint,
+ address _delegate
+ ) OFTAdapter(_token, _lzEndpoint, _delegate) Ownable(_delegate) {}
+}
diff --git a/examples/oft-adapter/contracts/mocks/MyERC20Mock.sol b/examples/oft-adapter/contracts/mocks/MyERC20Mock.sol
new file mode 100644
index 000000000..9ea57e789
--- /dev/null
+++ b/examples/oft-adapter/contracts/mocks/MyERC20Mock.sol
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: UNLICENSED
+pragma solidity ^0.8.20;
+
+import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
+
+// @dev WARNING: This is for testing purposes only
+contract MyERC20Mock is ERC20 {
+ constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol) {}
+
+ function mint(address _to, uint256 _amount) public {
+ _mint(_to, _amount);
+ }
+}
diff --git a/examples/oft-adapter/contracts/mocks/MyOFTAdapterMock.sol b/examples/oft-adapter/contracts/mocks/MyOFTAdapterMock.sol
new file mode 100644
index 000000000..59a32b77b
--- /dev/null
+++ b/examples/oft-adapter/contracts/mocks/MyOFTAdapterMock.sol
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: UNLICENSED
+pragma solidity ^0.8.22;
+
+import { MyOFTAdapter } from "../MyOFTAdapter.sol";
+
+// @dev WARNING: This is for testing purposes only
+contract MyOFTAdapterMock is MyOFTAdapter {
+ constructor(address _token, address _lzEndpoint, address _delegate) MyOFTAdapter(_token, _lzEndpoint, _delegate) {}
+}
diff --git a/examples/oft-adapter/contracts/mocks/MyOFTMock.sol b/examples/oft-adapter/contracts/mocks/MyOFTMock.sol
new file mode 100644
index 000000000..71ee1d841
--- /dev/null
+++ b/examples/oft-adapter/contracts/mocks/MyOFTMock.sol
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: UNLICENSED
+pragma solidity ^0.8.22;
+
+import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
+import { OFT } from "@layerzerolabs/oft-evm/contracts/OFT.sol";
+
+// @dev WARNING: This is for testing purposes only
+contract MyOFTMock is OFT {
+ constructor(
+ string memory _name,
+ string memory _symbol,
+ address _lzEndpoint,
+ address _delegate
+ ) OFT(_name, _symbol, _lzEndpoint, _delegate) Ownable(_delegate) {}
+
+ function mint(address _to, uint256 _amount) public {
+ _mint(_to, _amount);
+ }
+}
diff --git a/examples/oft-adapter/deploy/MyOFT.ts b/examples/oft-adapter/deploy/MyOFT.ts
new file mode 100644
index 000000000..5db617116
--- /dev/null
+++ b/examples/oft-adapter/deploy/MyOFT.ts
@@ -0,0 +1,60 @@
+import assert from 'assert'
+
+import { type DeployFunction } from 'hardhat-deploy/types'
+
+const contractName = 'MyOFT'
+
+const deploy: DeployFunction = async (hre) => {
+ const { getNamedAccounts, deployments } = hre
+
+ const { deploy } = deployments
+ const { deployer } = await getNamedAccounts()
+
+ assert(deployer, 'Missing named deployer account')
+
+ console.log(`Network: ${hre.network.name}`)
+ console.log(`Deployer: ${deployer}`)
+
+ // This is an external deployment pulled in from @layerzerolabs/lz-evm-sdk-v2
+ //
+ // @layerzerolabs/toolbox-hardhat takes care of plugging in the external deployments
+ // from @layerzerolabs packages based on the configuration in your hardhat config
+ //
+ // For this to work correctly, your network config must define an eid property
+ // set to `EndpointId` as defined in @layerzerolabs/lz-definitions
+ //
+ // For example:
+ //
+ // networks: {
+ // fuji: {
+ // ...
+ // eid: EndpointId.AVALANCHE_V2_TESTNET
+ // }
+ // }
+ const endpointV2Deployment = await hre.deployments.get('EndpointV2')
+
+ // If the oftAdapter configuration is defined on a network that is deploying an OFT,
+ // the deployment will log a warning and skip the deployment
+ if (hre.network.config.oftAdapter != null) {
+ console.warn(`oftAdapter configuration found on OFT deployment, skipping OFT deployment`)
+ return
+ }
+
+ const { address } = await deploy(contractName, {
+ from: deployer,
+ args: [
+ 'MyOFT', // name
+ 'MOFT', // symbol
+ endpointV2Deployment.address, // LayerZero's EndpointV2 address
+ deployer, // owner
+ ],
+ log: true,
+ skipIfAlreadyDeployed: false,
+ })
+
+ console.log(`Deployed contract: ${contractName}, network: ${hre.network.name}, address: ${address}`)
+}
+
+deploy.tags = [contractName]
+
+export default deploy
diff --git a/examples/oft-adapter/deploy/MyOFTAdapter.ts b/examples/oft-adapter/deploy/MyOFTAdapter.ts
new file mode 100644
index 000000000..3ccbc4be7
--- /dev/null
+++ b/examples/oft-adapter/deploy/MyOFTAdapter.ts
@@ -0,0 +1,60 @@
+import assert from 'assert'
+
+import { type DeployFunction } from 'hardhat-deploy/types'
+
+const contractName = 'MyOFTAdapter'
+
+const deploy: DeployFunction = async (hre) => {
+ const { getNamedAccounts, deployments } = hre
+
+ const { deploy } = deployments
+ const { deployer } = await getNamedAccounts()
+
+ assert(deployer, 'Missing named deployer account')
+
+ console.log(`Network: ${hre.network.name}`)
+ console.log(`Deployer: ${deployer}`)
+
+ // This is an external deployment pulled in from @layerzerolabs/lz-evm-sdk-v2
+ //
+ // @layerzerolabs/toolbox-hardhat takes care of plugging in the external deployments
+ // from @layerzerolabs packages based on the configuration in your hardhat config
+ //
+ // For this to work correctly, your network config must define an eid property
+ // set to `EndpointId` as defined in @layerzerolabs/lz-definitions
+ //
+ // For example:
+ //
+ // networks: {
+ // fuji: {
+ // ...
+ // eid: EndpointId.AVALANCHE_V2_TESTNET
+ // }
+ // }
+ const endpointV2Deployment = await hre.deployments.get('EndpointV2')
+
+ // The token address must be defined in hardhat.config.ts
+ // If the token address is not defined, the deployment will log a warning and skip the deployment
+ if (hre.network.config.oftAdapter == null) {
+ console.warn(`oftAdapter not configured on network config, skipping OFTWrapper deployment`)
+
+ return
+ }
+
+ const { address } = await deploy(contractName, {
+ from: deployer,
+ args: [
+ hre.network.config.oftAdapter.tokenAddress, // token address
+ endpointV2Deployment.address, // LayerZero's EndpointV2 address
+ deployer, // owner
+ ],
+ log: true,
+ skipIfAlreadyDeployed: false,
+ })
+
+ console.log(`Deployed contract: ${contractName}, network: ${hre.network.name}, address: ${address}`)
+}
+
+deploy.tags = [contractName]
+
+export default deploy
diff --git a/examples/oft-adapter/foundry.toml b/examples/oft-adapter/foundry.toml
new file mode 100644
index 000000000..37c3d3533
--- /dev/null
+++ b/examples/oft-adapter/foundry.toml
@@ -0,0 +1,27 @@
+[profile.default]
+solc-version = '0.8.22'
+src = 'contracts'
+out = 'out'
+test = 'test/foundry'
+cache_path = 'cache/foundry'
+libs = [
+ # We provide a set of useful contract utilities
+ # in the lib directory of @layerzerolabs/toolbox-foundry:
+ #
+ # - forge-std
+ # - ds-test
+ # - solidity-bytes-utils
+ 'node_modules/@layerzerolabs/toolbox-foundry/lib',
+ 'node_modules',
+]
+
+remappings = [
+ # Due to a misconfiguration of solidity-bytes-utils, an outdated version
+ # of forge-std is being dragged in
+ #
+ # To remedy this, we'll remap the ds-test and forge-std imports to ou own versions
+ 'ds-test/=node_modules/@layerzerolabs/toolbox-foundry/lib/ds-test',
+ 'forge-std/=node_modules/@layerzerolabs/toolbox-foundry/lib/forge-std',
+ '@layerzerolabs/=node_modules/@layerzerolabs/',
+ '@openzeppelin/=node_modules/@openzeppelin/',
+]
diff --git a/examples/oft-adapter/hardhat.config.ts b/examples/oft-adapter/hardhat.config.ts
new file mode 100644
index 000000000..200c314ef
--- /dev/null
+++ b/examples/oft-adapter/hardhat.config.ts
@@ -0,0 +1,83 @@
+// Get the environment configuration from .env file
+//
+// To make use of automatic environment setup:
+// - Duplicate .env.example file and name it .env
+// - Fill in the environment variables
+import 'dotenv/config'
+
+import 'hardhat-deploy'
+import 'hardhat-contract-sizer'
+import '@nomiclabs/hardhat-ethers'
+import '@layerzerolabs/toolbox-hardhat'
+import { HardhatUserConfig, HttpNetworkAccountsUserConfig } from 'hardhat/types'
+
+import { EndpointId } from '@layerzerolabs/lz-definitions'
+
+import './type-extensions'
+
+// Set your preferred authentication method
+//
+// If you prefer using a mnemonic, set a MNEMONIC environment variable
+// to a valid mnemonic
+const MNEMONIC = process.env.MNEMONIC
+
+// If you prefer to be authenticated using a private key, set a PRIVATE_KEY environment variable
+const PRIVATE_KEY = process.env.PRIVATE_KEY
+
+const accounts: HttpNetworkAccountsUserConfig | undefined = MNEMONIC
+ ? { mnemonic: MNEMONIC }
+ : PRIVATE_KEY
+ ? [PRIVATE_KEY]
+ : undefined
+
+if (accounts == null) {
+ console.warn(
+ 'Could not find MNEMONIC or PRIVATE_KEY environment variables. It will not be possible to execute transactions in your example.'
+ )
+}
+
+const config: HardhatUserConfig = {
+ paths: {
+ cache: 'cache/hardhat',
+ },
+ solidity: {
+ compilers: [
+ {
+ version: '0.8.22',
+ settings: {
+ optimizer: {
+ enabled: true,
+ runs: 200,
+ },
+ },
+ },
+ ],
+ },
+ networks: {
+ sepolia: {
+ eid: EndpointId.SEPOLIA_V2_TESTNET,
+ url: process.env.RPC_URL_SEPOLIA || 'https://rpc.sepolia.org/',
+ accounts,
+ oftAdapter: {
+ tokenAddress: '0x0', // Set the token address for the OFT adapter
+ },
+ },
+ fuji: {
+ eid: EndpointId.AVALANCHE_V2_TESTNET,
+ url: process.env.RPC_URL_FUJI || 'https://rpc.ankr.com/avalanche_fuji',
+ accounts,
+ },
+ amoy: {
+ eid: EndpointId.AMOY_V2_TESTNET,
+ url: process.env.RPC_URL_AMOY || 'https://polygon-amoy-bor-rpc.publicnode.com',
+ accounts,
+ },
+ },
+ namedAccounts: {
+ deployer: {
+ default: 0, // wallet address of index[0], of the mnemonic in .env
+ },
+ },
+}
+
+export default config
diff --git a/examples/oft-adapter/layerzero.config.ts b/examples/oft-adapter/layerzero.config.ts
new file mode 100644
index 000000000..8edff57ac
--- /dev/null
+++ b/examples/oft-adapter/layerzero.config.ts
@@ -0,0 +1,75 @@
+import { EndpointId } from '@layerzerolabs/lz-definitions'
+
+import type { OAppOmniGraphHardhat, OmniPointHardhat } from '@layerzerolabs/toolbox-hardhat'
+
+/**
+ * WARNING: ONLY 1 OFTAdapter should exist for a given global mesh.
+ * The token address for the adapter should be defined in hardhat.config. This will be used in deployment.
+ *
+ * for example:
+ *
+ * sepolia: {
+ * eid: EndpointId.SEPOLIA_V2_TESTNET,
+ * url: process.env.RPC_URL_SEPOLIA || 'https://rpc.sepolia.org/',
+ * accounts,
+ * oft-adapter: {
+ * tokenAddress: '0x0', // Set the token address for the OFT adapter
+ * },
+ * },
+ */
+const sepoliaContract: OmniPointHardhat = {
+ eid: EndpointId.SEPOLIA_V2_TESTNET,
+ contractName: 'MyOFTAdapter',
+}
+
+const fujiContract: OmniPointHardhat = {
+ eid: EndpointId.AVALANCHE_V2_TESTNET,
+ contractName: 'MyOFT',
+}
+
+const amoyContract: OmniPointHardhat = {
+ eid: EndpointId.AMOY_V2_TESTNET,
+ contractName: 'MyOFT',
+}
+
+const config: OAppOmniGraphHardhat = {
+ contracts: [
+ {
+ contract: fujiContract,
+ },
+ {
+ contract: sepoliaContract,
+ },
+ {
+ contract: amoyContract,
+ },
+ ],
+ connections: [
+ {
+ from: fujiContract,
+ to: sepoliaContract,
+ },
+ {
+ from: fujiContract,
+ to: amoyContract,
+ },
+ {
+ from: sepoliaContract,
+ to: fujiContract,
+ },
+ {
+ from: sepoliaContract,
+ to: amoyContract,
+ },
+ {
+ from: amoyContract,
+ to: sepoliaContract,
+ },
+ {
+ from: amoyContract,
+ to: fujiContract,
+ },
+ ],
+}
+
+export default config
diff --git a/examples/oft-adapter/package.json b/examples/oft-adapter/package.json
new file mode 100644
index 000000000..081d00365
--- /dev/null
+++ b/examples/oft-adapter/package.json
@@ -0,0 +1,76 @@
+{
+ "name": "@layerzerolabs/oft-adapter-example",
+ "version": "0.0.1",
+ "private": true,
+ "license": "MIT",
+ "scripts": {
+ "clean": "rm -rf artifacts cache out",
+ "compile": "$npm_execpath run compile:forge && $npm_execpath run compile:hardhat",
+ "compile:forge": "forge build",
+ "compile:hardhat": "hardhat compile",
+ "lint": "$npm_execpath run lint:js && $npm_execpath run lint:sol",
+ "lint:fix": "eslint --fix '**/*.{js,ts,json}' && prettier --write . && solhint 'contracts/**/*.sol' --fix --noPrompt",
+ "lint:js": "eslint '**/*.{js,ts,json}' && prettier --check .",
+ "lint:sol": "solhint 'contracts/**/*.sol'",
+ "test": "$npm_execpath run test:forge && $npm_execpath run test:hardhat",
+ "test:forge": "forge test",
+ "test:hardhat": "hardhat test"
+ },
+ "resolutions": {
+ "@nomicfoundation/edr": "0.3.5",
+ "ethers": "^5.7.2",
+ "hardhat-deploy": "^0.12.1"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.23.9",
+ "@layerzerolabs/eslint-config-next": "~2.3.3",
+ "@layerzerolabs/lz-definitions": "^2.3.25",
+ "@layerzerolabs/lz-evm-messagelib-v2": "^2.3.25",
+ "@layerzerolabs/lz-evm-oapp-v2": "^2.3.25",
+ "@layerzerolabs/lz-evm-protocol-v2": "^2.3.25",
+ "@layerzerolabs/lz-evm-v1-0.7": "^2.3.25",
+ "@layerzerolabs/lz-v2-utilities": "^2.3.25",
+ "@layerzerolabs/oft-evm": "^0.0.3",
+ "@layerzerolabs/prettier-config-next": "^2.3.25",
+ "@layerzerolabs/solhint-config": "^2.3.3",
+ "@layerzerolabs/test-devtools-evm-foundry": "~0.2.7",
+ "@layerzerolabs/toolbox-foundry": "~0.1.7",
+ "@layerzerolabs/toolbox-hardhat": "~0.2.35",
+ "@nomicfoundation/hardhat-ethers": "^3.0.5",
+ "@nomiclabs/hardhat-ethers": "^2.2.3",
+ "@openzeppelin/contracts": "^5.0.1",
+ "@openzeppelin/contracts-upgradeable": "^5.0.1",
+ "@rushstack/eslint-patch": "^1.7.0",
+ "@types/chai": "^4.3.11",
+ "@types/mocha": "^10.0.6",
+ "@types/node": "~18.18.14",
+ "chai": "^4.4.1",
+ "dotenv": "^16.4.1",
+ "eslint-plugin-jest-extended": "~2.0.0",
+ "ethers": "^5.7.2",
+ "hardhat": "^2.22.3",
+ "hardhat-contract-sizer": "^2.10.0",
+ "hardhat-deploy": "^0.12.1",
+ "mocha": "^10.2.0",
+ "prettier": "^3.2.5",
+ "solhint": "^4.1.1",
+ "solidity-bytes-utils": "^0.8.2",
+ "ts-node": "^10.9.2",
+ "typescript": "^5.3.3"
+ },
+ "engines": {
+ "node": ">=18.16.0"
+ },
+ "pnpm": {
+ "overrides": {
+ "@nomicfoundation/edr": "0.3.5",
+ "ethers": "^5.7.2",
+ "hardhat-deploy": "^0.12.1"
+ }
+ },
+ "overrides": {
+ "@nomicfoundation/edr": "0.3.5",
+ "ethers": "^5.7.2",
+ "hardhat-deploy": "^0.12.1"
+ }
+}
diff --git a/examples/oft-adapter/solhint.config.js b/examples/oft-adapter/solhint.config.js
new file mode 100644
index 000000000..52efe629c
--- /dev/null
+++ b/examples/oft-adapter/solhint.config.js
@@ -0,0 +1 @@
+module.exports = require('@layerzerolabs/solhint-config');
diff --git a/examples/oft-adapter/test/foundry/MyOFTAdapter.t.sol b/examples/oft-adapter/test/foundry/MyOFTAdapter.t.sol
new file mode 100644
index 000000000..37a1830e0
--- /dev/null
+++ b/examples/oft-adapter/test/foundry/MyOFTAdapter.t.sol
@@ -0,0 +1,180 @@
+// SPDX-License-Identifier: UNLICENSED
+pragma solidity ^0.8.20;
+
+// Mock imports
+import { OFTMock } from "../mocks/OFTMock.sol";
+import { OFTAdapterMock } from "../mocks/OFTAdapterMock.sol";
+import { ERC20Mock } from "../mocks/ERC20Mock.sol";
+import { OFTComposerMock } from "../mocks/OFTComposerMock.sol";
+
+// OApp imports
+import { IOAppOptionsType3, EnforcedOptionParam } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oapp/libs/OAppOptionsType3.sol";
+import { OptionsBuilder } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oapp/libs/OptionsBuilder.sol";
+
+// OFT imports
+import { IOFT, SendParam, OFTReceipt } from "@layerzerolabs/oft-evm/contracts/interfaces/IOFT.sol";
+import { MessagingFee, MessagingReceipt } from "@layerzerolabs/oft-evm/contracts/OFTCore.sol";
+import { OFTMsgCodec } from "@layerzerolabs/oft-evm/contracts/libs/OFTMsgCodec.sol";
+import { OFTComposeMsgCodec } from "@layerzerolabs/oft-evm/contracts/libs/OFTComposeMsgCodec.sol";
+
+// OZ imports
+import { IERC20 } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
+
+// Forge imports
+import "forge-std/console.sol";
+
+// DevTools imports
+import { TestHelperOz5 } from "@layerzerolabs/test-devtools-evm-foundry/contracts/TestHelperOz5.sol";
+
+contract MyOFTAdapterTest is TestHelperOz5 {
+ using OptionsBuilder for bytes;
+
+ uint32 private aEid = 1;
+ uint32 private bEid = 2;
+
+ ERC20Mock private aToken;
+ OFTAdapterMock private aOFTAdapter;
+ OFTMock private bOFT;
+
+ address private userA = address(0x1);
+ address private userB = address(0x2);
+ uint256 private initialBalance = 100 ether;
+
+ function setUp() public virtual override {
+ vm.deal(userA, 1000 ether);
+ vm.deal(userB, 1000 ether);
+
+ super.setUp();
+ setUpEndpoints(2, LibraryType.UltraLightNode);
+
+ aToken = ERC20Mock(_deployOApp(type(ERC20Mock).creationCode, abi.encode("Token", "TOKEN")));
+
+ aOFTAdapter = OFTAdapterMock(
+ _deployOApp(
+ type(OFTAdapterMock).creationCode,
+ abi.encode(address(aToken), address(endpoints[aEid]), address(this))
+ )
+ );
+
+ bOFT = OFTMock(
+ _deployOApp(
+ type(OFTMock).creationCode,
+ abi.encode("Token", "TOKEN", address(endpoints[bEid]), address(this))
+ )
+ );
+
+ // config and wire the ofts
+ address[] memory ofts = new address[](2);
+ ofts[0] = address(aOFTAdapter);
+ ofts[1] = address(bOFT);
+ this.wireOApps(ofts);
+
+ // mint tokens
+ aToken.mint(userA, initialBalance);
+ }
+
+ function test_constructor() public {
+ assertEq(aOFTAdapter.owner(), address(this));
+ assertEq(bOFT.owner(), address(this));
+
+ assertEq(aToken.balanceOf(userA), initialBalance);
+ assertEq(aToken.balanceOf(address(aOFTAdapter)), 0);
+ assertEq(bOFT.balanceOf(userB), 0);
+
+ assertEq(aOFTAdapter.token(), address(aToken));
+ assertEq(bOFT.token(), address(bOFT));
+ }
+
+ function test_send_oft_adapter() public {
+ uint256 tokensToSend = 1 ether;
+ bytes memory options = OptionsBuilder.newOptions().addExecutorLzReceiveOption(200000, 0);
+ SendParam memory sendParam = SendParam(
+ bEid,
+ addressToBytes32(userB),
+ tokensToSend,
+ tokensToSend,
+ options,
+ "",
+ ""
+ );
+ MessagingFee memory fee = aOFTAdapter.quoteSend(sendParam, false);
+
+ assertEq(aToken.balanceOf(userA), initialBalance);
+ assertEq(aToken.balanceOf(address(aOFTAdapter)), 0);
+ assertEq(bOFT.balanceOf(userB), 0);
+
+ vm.prank(userA);
+ aToken.approve(address(aOFTAdapter), tokensToSend);
+
+ vm.prank(userA);
+ aOFTAdapter.send{ value: fee.nativeFee }(sendParam, fee, payable(address(this)));
+ verifyPackets(bEid, addressToBytes32(address(bOFT)));
+
+ assertEq(aToken.balanceOf(userA), initialBalance - tokensToSend);
+ assertEq(aToken.balanceOf(address(aOFTAdapter)), tokensToSend);
+ assertEq(bOFT.balanceOf(userB), tokensToSend);
+ }
+
+ function test_send_oft_adapter_compose_msg() public {
+ uint256 tokensToSend = 1 ether;
+
+ OFTComposerMock composer = new OFTComposerMock();
+
+ bytes memory options = OptionsBuilder
+ .newOptions()
+ .addExecutorLzReceiveOption(200000, 0)
+ .addExecutorLzComposeOption(0, 500000, 0);
+ bytes memory composeMsg = hex"1234";
+ SendParam memory sendParam = SendParam(
+ bEid,
+ addressToBytes32(address(composer)),
+ tokensToSend,
+ tokensToSend,
+ options,
+ composeMsg,
+ ""
+ );
+ MessagingFee memory fee = aOFTAdapter.quoteSend(sendParam, false);
+
+ assertEq(aToken.balanceOf(userA), initialBalance);
+ assertEq(aToken.balanceOf(address(aOFTAdapter)), 0);
+ assertEq(bOFT.balanceOf(userB), 0);
+
+ vm.prank(userA);
+ aToken.approve(address(aOFTAdapter), tokensToSend);
+
+ vm.prank(userA);
+ (MessagingReceipt memory msgReceipt, OFTReceipt memory oftReceipt) = aOFTAdapter.send{ value: fee.nativeFee }(
+ sendParam,
+ fee,
+ payable(address(this))
+ );
+ verifyPackets(bEid, addressToBytes32(address(bOFT)));
+
+ // lzCompose params
+ uint32 dstEid_ = bEid;
+ address from_ = address(bOFT);
+ bytes memory options_ = options;
+ bytes32 guid_ = msgReceipt.guid;
+ address to_ = address(composer);
+ bytes memory composerMsg_ = OFTComposeMsgCodec.encode(
+ msgReceipt.nonce,
+ aEid,
+ oftReceipt.amountReceivedLD,
+ abi.encodePacked(addressToBytes32(userA), composeMsg)
+ );
+ this.lzCompose(dstEid_, from_, options_, guid_, to_, composerMsg_);
+
+ assertEq(aToken.balanceOf(userA), initialBalance - tokensToSend);
+ assertEq(aToken.balanceOf(address(aOFTAdapter)), tokensToSend);
+ assertEq(bOFT.balanceOf(address(composer)), tokensToSend);
+
+ assertEq(composer.from(), from_);
+ assertEq(composer.guid(), guid_);
+ assertEq(composer.message(), composerMsg_);
+ assertEq(composer.executor(), address(this));
+ assertEq(composer.extraData(), composerMsg_); // default to setting the extraData to the message as well to test
+ }
+
+ // TODO import the rest of oft tests?
+}
diff --git a/examples/oft-adapter/test/hardhat/MyOFTAdapter.test.ts b/examples/oft-adapter/test/hardhat/MyOFTAdapter.test.ts
new file mode 100644
index 000000000..09073aa51
--- /dev/null
+++ b/examples/oft-adapter/test/hardhat/MyOFTAdapter.test.ts
@@ -0,0 +1,117 @@
+import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'
+import { expect } from 'chai'
+import { Contract, ContractFactory } from 'ethers'
+import { deployments, ethers } from 'hardhat'
+
+import { Options } from '@layerzerolabs/lz-v2-utilities'
+
+describe('MyOFTAdapter Test', function () {
+ // Constant representing a mock Endpoint ID for testing purposes
+ const eidA = 1
+ const eidB = 2
+ // Declaration of variables to be used in the test suite
+ let MyOFTAdapter: ContractFactory
+ let MyOFT: ContractFactory
+ let ERC20Mock: ContractFactory
+ let EndpointV2Mock: ContractFactory
+ let ownerA: SignerWithAddress
+ let ownerB: SignerWithAddress
+ let endpointOwner: SignerWithAddress
+ let token: Contract
+ let myOFTAdapter: Contract
+ let myOFTB: Contract
+ let mockEndpointV2A: Contract
+ let mockEndpointV2B: Contract
+
+ // Before hook for setup that runs once before all tests in the block
+ before(async function () {
+ // Contract factory for our tested contract
+ //
+ // We are using a derived contract that exposes a mint() function for testing purposes
+ MyOFTAdapter = await ethers.getContractFactory('MyOFTAdapterMock')
+
+ MyOFT = await ethers.getContractFactory('MyOFTMock')
+
+ ERC20Mock = await ethers.getContractFactory('MyERC20Mock')
+
+ // Fetching the first three signers (accounts) from Hardhat's local Ethereum network
+ const signers = await ethers.getSigners()
+
+ ownerA = signers.at(0)!
+ ownerB = signers.at(1)!
+ endpointOwner = signers.at(2)!
+
+ // The EndpointV2Mock contract comes from @layerzerolabs/test-devtools-evm-hardhat package
+ // and its artifacts are connected as external artifacts to this project
+ //
+ // Unfortunately, hardhat itself does not yet provide a way of connecting external artifacts,
+ // so we rely on hardhat-deploy to create a ContractFactory for EndpointV2Mock
+ //
+ // See https://github.com/NomicFoundation/hardhat/issues/1040
+ const EndpointV2MockArtifact = await deployments.getArtifact('EndpointV2Mock')
+ EndpointV2Mock = new ContractFactory(EndpointV2MockArtifact.abi, EndpointV2MockArtifact.bytecode, endpointOwner)
+ })
+
+ // beforeEach hook for setup that runs before each test in the block
+ beforeEach(async function () {
+ // Deploying a mock LZEndpoint with the given Endpoint ID
+ mockEndpointV2A = await EndpointV2Mock.deploy(eidA)
+ mockEndpointV2B = await EndpointV2Mock.deploy(eidB)
+
+ token = await ERC20Mock.deploy('Token', 'TOKEN')
+
+ // Deploying two instances of MyOFT contract with different identifiers and linking them to the mock LZEndpoint
+ myOFTAdapter = await MyOFTAdapter.deploy(token.address, mockEndpointV2A.address, ownerA.address)
+ myOFTB = await MyOFT.deploy('bOFT', 'bOFT', mockEndpointV2B.address, ownerB.address)
+
+ // Setting destination endpoints in the LZEndpoint mock for each MyOFT instance
+ await mockEndpointV2A.setDestLzEndpoint(myOFTB.address, mockEndpointV2B.address)
+ await mockEndpointV2B.setDestLzEndpoint(myOFTAdapter.address, mockEndpointV2A.address)
+
+ // Setting each MyOFT instance as a peer of the other in the mock LZEndpoint
+ await myOFTAdapter.connect(ownerA).setPeer(eidB, ethers.utils.zeroPad(myOFTB.address, 32))
+ await myOFTB.connect(ownerB).setPeer(eidA, ethers.utils.zeroPad(myOFTAdapter.address, 32))
+ })
+
+ // A test case to verify token transfer functionality
+ it('should send a token from A address to B address via OFTAdapter/OFT', async function () {
+ // Minting an initial amount of tokens to ownerA's address in the myOFTA contract
+ const initialAmount = ethers.utils.parseEther('100')
+ await token.mint(ownerA.address, initialAmount)
+
+ // Defining the amount of tokens to send and constructing the parameters for the send operation
+ const tokensToSend = ethers.utils.parseEther('1')
+
+ // Defining extra message execution options for the send operation
+ const options = Options.newOptions().addExecutorLzReceiveOption(200000, 0).toHex().toString()
+
+ const sendParam = [
+ eidB,
+ ethers.utils.zeroPad(ownerB.address, 32),
+ tokensToSend,
+ tokensToSend,
+ options,
+ '0x',
+ '0x',
+ ]
+
+ // Fetching the native fee for the token send operation
+ const [nativeFee] = await myOFTAdapter.quoteSend(sendParam, false)
+
+ // Approving the native fee to be spent by the myOFTA contract
+ await token.connect(ownerA).approve(myOFTAdapter.address, tokensToSend)
+
+ // Executing the send operation from myOFTA contract
+ await myOFTAdapter.send(sendParam, [nativeFee, 0], ownerA.address, { value: nativeFee })
+
+ // Fetching the final token balances of ownerA and ownerB
+ const finalBalanceA = await token.balanceOf(ownerA.address)
+ const finalBalanceAdapter = await token.balanceOf(myOFTAdapter.address)
+ const finalBalanceB = await myOFTB.balanceOf(ownerB.address)
+
+ // Asserting that the final balances are as expected after the send operation
+ expect(finalBalanceA).eql(initialAmount.sub(tokensToSend))
+ expect(finalBalanceAdapter).eql(tokensToSend)
+ expect(finalBalanceB).eql(tokensToSend)
+ })
+})
diff --git a/examples/oft-adapter/test/mocks/ERC20Mock.sol b/examples/oft-adapter/test/mocks/ERC20Mock.sol
new file mode 100644
index 000000000..6ce17e418
--- /dev/null
+++ b/examples/oft-adapter/test/mocks/ERC20Mock.sol
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: UNLICENSED
+pragma solidity ^0.8.20;
+
+import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
+
+contract ERC20Mock is ERC20 {
+ constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol) {}
+
+ function mint(address _to, uint256 _amount) public {
+ _mint(_to, _amount);
+ }
+}
diff --git a/examples/oft-adapter/test/mocks/OFTAdapterMock.sol b/examples/oft-adapter/test/mocks/OFTAdapterMock.sol
new file mode 100644
index 000000000..08a2df0d5
--- /dev/null
+++ b/examples/oft-adapter/test/mocks/OFTAdapterMock.sol
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: UNLICENSED
+pragma solidity ^0.8.0;
+
+import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
+import { OFTAdapter } from "@layerzerolabs/oft-evm/contracts/OFTAdapter.sol";
+
+contract OFTAdapterMock is OFTAdapter {
+ constructor(
+ address _token,
+ address _lzEndpoint,
+ address _delegate
+ ) OFTAdapter(_token, _lzEndpoint, _delegate) Ownable(_delegate) {}
+
+ // @dev expose internal functions for testing purposes
+ function debit(
+ uint256 _amountToSendLD,
+ uint256 _minAmountToCreditLD,
+ uint32 _dstEid
+ ) public returns (uint256 amountDebitedLD, uint256 amountToCreditLD) {
+ return _debit(msg.sender, _amountToSendLD, _minAmountToCreditLD, _dstEid);
+ }
+
+ function debitView(
+ uint256 _amountToSendLD,
+ uint256 _minAmountToCreditLD,
+ uint32 _dstEid
+ ) public view returns (uint256 amountDebitedLD, uint256 amountToCreditLD) {
+ return _debitView(_amountToSendLD, _minAmountToCreditLD, _dstEid);
+ }
+
+ function credit(address _to, uint256 _amountToCreditLD, uint32 _srcEid) public returns (uint256 amountReceivedLD) {
+ return _credit(_to, _amountToCreditLD, _srcEid);
+ }
+
+ function removeDust(uint256 _amountLD) public view returns (uint256 amountLD) {
+ return _removeDust(_amountLD);
+ }
+}
diff --git a/examples/oft-adapter/test/mocks/OFTComposerMock.sol b/examples/oft-adapter/test/mocks/OFTComposerMock.sol
new file mode 100644
index 000000000..26354d4ad
--- /dev/null
+++ b/examples/oft-adapter/test/mocks/OFTComposerMock.sol
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: UNLICENSED
+pragma solidity ^0.8.0;
+
+import { IOAppComposer } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oapp/interfaces/IOAppComposer.sol";
+
+contract OFTComposerMock is IOAppComposer {
+ // default empty values for testing a lzCompose received message
+ address public from;
+ bytes32 public guid;
+ bytes public message;
+ address public executor;
+ bytes public extraData;
+
+ function lzCompose(
+ address _from,
+ bytes32 _guid,
+ bytes calldata _message,
+ address _executor,
+ bytes calldata /*_extraData*/
+ ) external payable {
+ from = _from;
+ guid = _guid;
+ message = _message;
+ executor = _executor;
+ extraData = _message;
+ }
+}
diff --git a/examples/oft-adapter/test/mocks/OFTMock.sol b/examples/oft-adapter/test/mocks/OFTMock.sol
new file mode 100644
index 000000000..cef8770f5
--- /dev/null
+++ b/examples/oft-adapter/test/mocks/OFTMock.sol
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: UNLICENSED
+pragma solidity ^0.8.0;
+
+import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
+import { OFT } from "@layerzerolabs/oft-evm/contracts/OFT.sol";
+import { SendParam } from "@layerzerolabs/oft-evm/contracts/OFTCore.sol";
+
+contract OFTMock is OFT {
+ constructor(
+ string memory _name,
+ string memory _symbol,
+ address _lzEndpoint,
+ address _delegate
+ ) Ownable(_delegate) OFT(_name, _symbol, _lzEndpoint, _delegate) {}
+
+ function mint(address _to, uint256 _amount) public {
+ _mint(_to, _amount);
+ }
+
+ // @dev expose internal functions for testing purposes
+ function debit(
+ uint256 _amountToSendLD,
+ uint256 _minAmountToCreditLD,
+ uint32 _dstEid
+ ) public returns (uint256 amountDebitedLD, uint256 amountToCreditLD) {
+ return _debit(msg.sender, _amountToSendLD, _minAmountToCreditLD, _dstEid);
+ }
+
+ function debitView(
+ uint256 _amountToSendLD,
+ uint256 _minAmountToCreditLD,
+ uint32 _dstEid
+ ) public view returns (uint256 amountDebitedLD, uint256 amountToCreditLD) {
+ return _debitView(_amountToSendLD, _minAmountToCreditLD, _dstEid);
+ }
+
+ function removeDust(uint256 _amountLD) public view returns (uint256 amountLD) {
+ return _removeDust(_amountLD);
+ }
+
+ function toLD(uint64 _amountSD) public view returns (uint256 amountLD) {
+ return _toLD(_amountSD);
+ }
+
+ function toSD(uint256 _amountLD) public view returns (uint64 amountSD) {
+ return _toSD(_amountLD);
+ }
+
+ function credit(address _to, uint256 _amountToCreditLD, uint32 _srcEid) public returns (uint256 amountReceivedLD) {
+ return _credit(_to, _amountToCreditLD, _srcEid);
+ }
+
+ function buildMsgAndOptions(
+ SendParam calldata _sendParam,
+ uint256 _amountToCreditLD
+ ) public view returns (bytes memory message, bytes memory options) {
+ return _buildMsgAndOptions(_sendParam, _amountToCreditLD);
+ }
+}
diff --git a/examples/oft-adapter/tsconfig.json b/examples/oft-adapter/tsconfig.json
new file mode 100644
index 000000000..027ad0f3f
--- /dev/null
+++ b/examples/oft-adapter/tsconfig.json
@@ -0,0 +1,13 @@
+{
+ "exclude": ["node_modules"],
+ "include": ["deploy", "tasks", "test", "hardhat.config.ts"],
+ "compilerOptions": {
+ "target": "es2020",
+ "module": "commonjs",
+ "esModuleInterop": true,
+ "forceConsistentCasingInFileNames": true,
+ "strict": true,
+ "skipLibCheck": true,
+ "resolveJsonModule": true
+ }
+}
diff --git a/examples/oft-adapter/type-extensions.ts b/examples/oft-adapter/type-extensions.ts
new file mode 100644
index 000000000..ffc2b722e
--- /dev/null
+++ b/examples/oft-adapter/type-extensions.ts
@@ -0,0 +1,23 @@
+import 'hardhat/types/config'
+
+interface OftAdapterConfig {
+ tokenAddress: string
+}
+
+declare module 'hardhat/types/config' {
+ interface HardhatNetworkUserConfig {
+ oftAdapter?: never
+ }
+
+ interface HardhatNetworkConfig {
+ oftAdapter?: never
+ }
+
+ interface HttpNetworkUserConfig {
+ oftAdapter?: OftAdapterConfig
+ }
+
+ interface HttpNetworkConfig {
+ oftAdapter?: OftAdapterConfig
+ }
+}
diff --git a/packages/create-lz-oapp/src/config.ts b/packages/create-lz-oapp/src/config.ts
index dd67e439f..03ce32169 100644
--- a/packages/create-lz-oapp/src/config.ts
+++ b/packages/create-lz-oapp/src/config.ts
@@ -38,6 +38,13 @@ export const EXAMPLES: Example[] = [
directory: 'examples/onft721',
ref,
},
+ {
+ id: 'oft-adapter',
+ label: 'OFTAdapter',
+ repository,
+ directory: 'examples/oft-adapter',
+ ref,
+ },
]
export const PACKAGE_MANAGERS: PackageManager[] = [
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index cbb346065..5fc83993a 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -289,6 +289,114 @@ importers:
specifier: ^5.3.3
version: 5.3.3
+ examples/oft-adapter:
+ devDependencies:
+ '@babel/core':
+ specifier: ^7.23.9
+ version: 7.23.9
+ '@layerzerolabs/eslint-config-next':
+ specifier: ~2.3.3
+ version: 2.3.3(typescript@5.5.3)
+ '@layerzerolabs/lz-definitions':
+ specifier: ^2.3.25
+ version: 2.3.25
+ '@layerzerolabs/lz-evm-messagelib-v2':
+ specifier: ^2.3.25
+ version: 2.3.29(@axelar-network/axelar-gmp-sdk-solidity@5.9.0)(@chainlink/contracts-ccip@0.7.6)(@eth-optimism/contracts@0.6.0)(@layerzerolabs/lz-evm-protocol-v2@2.3.29)(@layerzerolabs/lz-evm-v1-0.7@2.3.29)(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2)
+ '@layerzerolabs/lz-evm-oapp-v2':
+ specifier: ^2.3.25
+ version: 2.3.29(@layerzerolabs/lz-evm-messagelib-v2@2.3.29)(@layerzerolabs/lz-evm-protocol-v2@2.3.29)(@layerzerolabs/lz-evm-v1-0.7@2.3.29)(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2)
+ '@layerzerolabs/lz-evm-protocol-v2':
+ specifier: ^2.3.25
+ version: 2.3.29(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2)
+ '@layerzerolabs/lz-evm-v1-0.7':
+ specifier: ^2.3.25
+ version: 2.3.29(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.4)
+ '@layerzerolabs/lz-v2-utilities':
+ specifier: ^2.3.25
+ version: 2.3.25
+ '@layerzerolabs/oft-evm':
+ specifier: ^0.0.3
+ version: link:../../packages/oft-evm
+ '@layerzerolabs/prettier-config-next':
+ specifier: ^2.3.25
+ version: 2.3.25
+ '@layerzerolabs/solhint-config':
+ specifier: ^2.3.3
+ version: 2.3.3(typescript@5.5.3)
+ '@layerzerolabs/test-devtools-evm-foundry':
+ specifier: ~0.2.7
+ version: link:../../packages/test-devtools-evm-foundry
+ '@layerzerolabs/toolbox-foundry':
+ specifier: ~0.1.7
+ version: link:../../packages/toolbox-foundry
+ '@layerzerolabs/toolbox-hardhat':
+ specifier: ~0.2.35
+ version: link:../../packages/toolbox-hardhat
+ '@nomicfoundation/hardhat-ethers':
+ specifier: ^3.0.5
+ version: 3.0.5(ethers@5.7.2)(hardhat@2.22.3)
+ '@nomiclabs/hardhat-ethers':
+ specifier: ^2.2.3
+ version: 2.2.3(ethers@5.7.2)(hardhat@2.22.3)
+ '@openzeppelin/contracts':
+ specifier: ^5.0.1
+ version: 5.0.2
+ '@openzeppelin/contracts-upgradeable':
+ specifier: ^5.0.1
+ version: 5.0.2(@openzeppelin/contracts@5.0.2)
+ '@rushstack/eslint-patch':
+ specifier: ^1.7.0
+ version: 1.7.0
+ '@types/chai':
+ specifier: ^4.3.11
+ version: 4.3.11
+ '@types/mocha':
+ specifier: ^10.0.6
+ version: 10.0.6
+ '@types/node':
+ specifier: ~18.18.14
+ version: 18.18.14
+ chai:
+ specifier: ^4.4.1
+ version: 4.4.1
+ dotenv:
+ specifier: ^16.4.1
+ version: 16.4.5
+ eslint-plugin-jest-extended:
+ specifier: ~2.0.0
+ version: 2.0.0(eslint@8.57.0)(typescript@5.5.3)
+ ethers:
+ specifier: ^5.7.2
+ version: 5.7.2
+ hardhat:
+ specifier: ^2.22.3
+ version: 2.22.3(ts-node@10.9.2)(typescript@5.5.3)
+ hardhat-contract-sizer:
+ specifier: ^2.10.0
+ version: 2.10.0(hardhat@2.22.3)
+ hardhat-deploy:
+ specifier: ^0.12.1
+ version: 0.12.4
+ mocha:
+ specifier: ^10.2.0
+ version: 10.2.0
+ prettier:
+ specifier: ^3.2.5
+ version: 3.2.5
+ solhint:
+ specifier: ^4.1.1
+ version: 4.1.1(typescript@5.5.3)
+ solidity-bytes-utils:
+ specifier: ^0.8.2
+ version: 0.8.2
+ ts-node:
+ specifier: ^10.9.2
+ version: 10.9.2(@swc/core@1.4.0)(@types/node@18.18.14)(typescript@5.5.3)
+ typescript:
+ specifier: ^5.3.3
+ version: 5.5.3
+
examples/onft721:
devDependencies:
'@babel/core':
@@ -2056,13 +2164,13 @@ importers:
version: 2.3.25
'@layerzerolabs/lz-evm-messagelib-v2':
specifier: ^2.3.25
- version: 2.3.25(@axelar-network/axelar-gmp-sdk-solidity@5.9.0)(@chainlink/contracts-ccip@0.7.6)(@eth-optimism/contracts@0.6.0)(@layerzerolabs/lz-evm-protocol-v2@2.3.25)(@layerzerolabs/lz-evm-v1-0.7@2.3.29)(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2)
+ version: 2.3.29(@axelar-network/axelar-gmp-sdk-solidity@5.9.0)(@chainlink/contracts-ccip@0.7.6)(@eth-optimism/contracts@0.6.0)(@layerzerolabs/lz-evm-protocol-v2@2.3.29)(@layerzerolabs/lz-evm-v1-0.7@2.3.29)(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2)
'@layerzerolabs/lz-evm-oapp-v2':
specifier: ^2.3.25
- version: 2.3.29(@layerzerolabs/lz-evm-messagelib-v2@2.3.25)(@layerzerolabs/lz-evm-protocol-v2@2.3.25)(@layerzerolabs/lz-evm-v1-0.7@2.3.29)(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2)
+ version: 2.3.29(@layerzerolabs/lz-evm-messagelib-v2@2.3.29)(@layerzerolabs/lz-evm-protocol-v2@2.3.29)(@layerzerolabs/lz-evm-v1-0.7@2.3.29)(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2)
'@layerzerolabs/lz-evm-protocol-v2':
specifier: ^2.3.25
- version: 2.3.25(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2)
+ version: 2.3.29(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2)
'@layerzerolabs/lz-evm-sdk-v1':
specifier: ^2.3.25
version: 2.3.25
@@ -4525,6 +4633,26 @@ packages:
- typescript
dev: true
+ /@layerzerolabs/eslint-config-next@2.3.3(typescript@5.5.3):
+ resolution: {integrity: sha512-zeq0LZkSPI2tm6M1fRmmPA6gzTAUg3rux074FV+8N+PyC53/DhPUHT/DYvTHl0/+F04nFp8MD+yYSHReVIQLNQ==}
+ dependencies:
+ '@typescript-eslint/eslint-plugin': 7.7.1(@typescript-eslint/parser@7.7.1)(eslint@8.57.0)(typescript@5.5.3)
+ '@typescript-eslint/parser': 7.7.1(eslint@8.57.0)(typescript@5.5.3)
+ eslint: 8.57.0
+ eslint-config-prettier: 9.1.0(eslint@8.57.0)
+ eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.7.1)(eslint-plugin-import@2.29.1)(eslint@8.57.0)
+ eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.7.1)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
+ eslint-plugin-prettier: 5.1.3(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.2.5)
+ eslint-plugin-unused-imports: 3.1.0(@typescript-eslint/eslint-plugin@7.7.1)(eslint@8.57.0)
+ prettier: 3.2.5
+ transitivePeerDependencies:
+ - '@types/eslint'
+ - eslint-import-resolver-node
+ - eslint-import-resolver-webpack
+ - supports-color
+ - typescript
+ dev: true
+
/@layerzerolabs/evm-sdks-core@2.3.25:
resolution: {integrity: sha512-2qUeEVMnYFnj3MrEWGmrXKn249ohfvjSyDsjivJJbwu9rlxsk/zclb+May1SCO0UcbPfgILVkldZoL4LyqrwnA==}
dependencies:
@@ -4740,7 +4868,7 @@ packages:
solidity-bytes-utils: 0.8.2
dev: true
- /@layerzerolabs/lz-evm-messagelib-v2@2.3.25(@axelar-network/axelar-gmp-sdk-solidity@5.9.0)(@chainlink/contracts-ccip@0.7.6)(@eth-optimism/contracts@0.6.0)(@layerzerolabs/lz-evm-protocol-v2@2.3.25)(@layerzerolabs/lz-evm-v1-0.7@2.3.29)(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2):
+ /@layerzerolabs/lz-evm-messagelib-v2@2.3.25(@axelar-network/axelar-gmp-sdk-solidity@5.9.0)(@chainlink/contracts-ccip@0.7.6)(@eth-optimism/contracts@0.6.0)(@layerzerolabs/lz-evm-protocol-v2@2.3.29)(@layerzerolabs/lz-evm-v1-0.7@2.3.29)(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.1)(solidity-bytes-utils@0.8.2):
resolution: {integrity: sha512-QcIqNry0qia7Rf/7PR1t4VibQT2QGZdyLzsiKICzb2k8EpwiUYnHriIX6VBeFklVOBc3D9ffwZ/bBvsg9NykKg==}
peerDependencies:
'@arbitrum/nitro-contracts': ^1.1.0
@@ -4760,23 +4888,23 @@ packages:
'@axelar-network/axelar-gmp-sdk-solidity': 5.9.0
'@chainlink/contracts-ccip': 0.7.6(ethers@5.7.2)
'@eth-optimism/contracts': 0.6.0(ethers@5.7.2)
- '@layerzerolabs/lz-evm-protocol-v2': 2.3.25(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2)
- '@layerzerolabs/lz-evm-v1-0.7': 2.3.29(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.4)
+ '@layerzerolabs/lz-evm-protocol-v2': 2.3.29(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.1)(solidity-bytes-utils@0.8.2)
+ '@layerzerolabs/lz-evm-v1-0.7': 2.3.29(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.1)
'@openzeppelin/contracts': 5.0.2
'@openzeppelin/contracts-upgradeable': 5.0.2(@openzeppelin/contracts@5.0.2)
- hardhat-deploy: 0.12.4
+ hardhat-deploy: 0.12.1
solidity-bytes-utils: 0.8.2
dev: true
- /@layerzerolabs/lz-evm-messagelib-v2@2.3.25(@axelar-network/axelar-gmp-sdk-solidity@5.9.0)(@chainlink/contracts-ccip@0.7.6)(@eth-optimism/contracts@0.6.0)(@layerzerolabs/lz-evm-protocol-v2@2.3.29)(@layerzerolabs/lz-evm-v1-0.7@2.3.29)(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.1)(solidity-bytes-utils@0.8.2):
- resolution: {integrity: sha512-QcIqNry0qia7Rf/7PR1t4VibQT2QGZdyLzsiKICzb2k8EpwiUYnHriIX6VBeFklVOBc3D9ffwZ/bBvsg9NykKg==}
+ /@layerzerolabs/lz-evm-messagelib-v2@2.3.29(@axelar-network/axelar-gmp-sdk-solidity@5.9.0)(@chainlink/contracts-ccip@0.7.6)(@eth-optimism/contracts@0.6.0)(@layerzerolabs/lz-evm-protocol-v2@2.3.29)(@layerzerolabs/lz-evm-v1-0.7@2.3.29)(@openzeppelin/contracts-upgradeable@4.9.5)(@openzeppelin/contracts@4.9.5)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2):
+ resolution: {integrity: sha512-idkRR+xTY2LX/KbA79P4bIf5niLEXwmMQvje+b0froiT8YqIpyrHzHn5XjasyOSW8VMClyWuios1xPoawfSSjA==}
peerDependencies:
'@arbitrum/nitro-contracts': ^1.1.0
'@axelar-network/axelar-gmp-sdk-solidity': ^5.6.4
'@chainlink/contracts-ccip': ^0.7.6
'@eth-optimism/contracts': ^0.6.0
- '@layerzerolabs/lz-evm-protocol-v2': ^2.3.25
- '@layerzerolabs/lz-evm-v1-0.7': ^2.3.25
+ '@layerzerolabs/lz-evm-protocol-v2': ^2.3.29
+ '@layerzerolabs/lz-evm-v1-0.7': ^2.3.29
'@openzeppelin/contracts': ^4.8.1 || ^5.0.0
'@openzeppelin/contracts-upgradeable': ^4.8.1 || ^5.0.0
hardhat-deploy: ^0.12.1
@@ -4788,15 +4916,15 @@ packages:
'@axelar-network/axelar-gmp-sdk-solidity': 5.9.0
'@chainlink/contracts-ccip': 0.7.6(ethers@5.7.2)
'@eth-optimism/contracts': 0.6.0(ethers@5.7.2)
- '@layerzerolabs/lz-evm-protocol-v2': 2.3.29(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.1)(solidity-bytes-utils@0.8.2)
- '@layerzerolabs/lz-evm-v1-0.7': 2.3.29(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.1)
- '@openzeppelin/contracts': 5.0.2
- '@openzeppelin/contracts-upgradeable': 5.0.2(@openzeppelin/contracts@5.0.2)
- hardhat-deploy: 0.12.1
+ '@layerzerolabs/lz-evm-protocol-v2': 2.3.29(@openzeppelin/contracts-upgradeable@4.9.5)(@openzeppelin/contracts@4.9.5)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2)
+ '@layerzerolabs/lz-evm-v1-0.7': 2.3.29(@openzeppelin/contracts-upgradeable@4.9.5)(@openzeppelin/contracts@4.9.5)(hardhat-deploy@0.12.4)
+ '@openzeppelin/contracts': 4.9.5
+ '@openzeppelin/contracts-upgradeable': 4.9.5
+ hardhat-deploy: 0.12.4
solidity-bytes-utils: 0.8.2
dev: true
- /@layerzerolabs/lz-evm-messagelib-v2@2.3.29(@axelar-network/axelar-gmp-sdk-solidity@5.9.0)(@chainlink/contracts-ccip@0.7.6)(@eth-optimism/contracts@0.6.0)(@layerzerolabs/lz-evm-protocol-v2@2.3.29)(@layerzerolabs/lz-evm-v1-0.7@2.3.29)(@openzeppelin/contracts-upgradeable@4.9.5)(@openzeppelin/contracts@4.9.5)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2):
+ /@layerzerolabs/lz-evm-messagelib-v2@2.3.29(@axelar-network/axelar-gmp-sdk-solidity@5.9.0)(@chainlink/contracts-ccip@0.7.6)(@eth-optimism/contracts@0.6.0)(@layerzerolabs/lz-evm-protocol-v2@2.3.29)(@layerzerolabs/lz-evm-v1-0.7@2.3.29)(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2):
resolution: {integrity: sha512-idkRR+xTY2LX/KbA79P4bIf5niLEXwmMQvje+b0froiT8YqIpyrHzHn5XjasyOSW8VMClyWuios1xPoawfSSjA==}
peerDependencies:
'@arbitrum/nitro-contracts': ^1.1.0
@@ -4816,10 +4944,10 @@ packages:
'@axelar-network/axelar-gmp-sdk-solidity': 5.9.0
'@chainlink/contracts-ccip': 0.7.6(ethers@5.7.2)
'@eth-optimism/contracts': 0.6.0(ethers@5.7.2)
- '@layerzerolabs/lz-evm-protocol-v2': 2.3.29(@openzeppelin/contracts-upgradeable@4.9.5)(@openzeppelin/contracts@4.9.5)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2)
- '@layerzerolabs/lz-evm-v1-0.7': 2.3.29(@openzeppelin/contracts-upgradeable@4.9.5)(@openzeppelin/contracts@4.9.5)(hardhat-deploy@0.12.4)
- '@openzeppelin/contracts': 4.9.5
- '@openzeppelin/contracts-upgradeable': 4.9.5
+ '@layerzerolabs/lz-evm-protocol-v2': 2.3.29(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2)
+ '@layerzerolabs/lz-evm-v1-0.7': 2.3.29(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.4)
+ '@openzeppelin/contracts': 5.0.2
+ '@openzeppelin/contracts-upgradeable': 5.0.2(@openzeppelin/contracts@5.0.2)
hardhat-deploy: 0.12.4
solidity-bytes-utils: 0.8.2
dev: true
@@ -4945,7 +5073,7 @@ packages:
solidity-bytes-utils: 0.8.2
dev: true
- /@layerzerolabs/lz-evm-oapp-v2@2.3.29(@layerzerolabs/lz-evm-messagelib-v2@2.3.25)(@layerzerolabs/lz-evm-protocol-v2@2.3.25)(@layerzerolabs/lz-evm-v1-0.7@2.3.29)(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2):
+ /@layerzerolabs/lz-evm-oapp-v2@2.3.29(@layerzerolabs/lz-evm-messagelib-v2@2.3.29)(@layerzerolabs/lz-evm-protocol-v2@2.3.29)(@layerzerolabs/lz-evm-v1-0.7@2.3.29)(@openzeppelin/contracts-upgradeable@4.9.5)(@openzeppelin/contracts@4.9.5)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2):
resolution: {integrity: sha512-HFuHVCUjZNOjKuhRDBbK2NSGA7sMwFhXRqy0veym9kECDwtHdazLfYmOGhu1amRfomc+eq+KBakJl2XI8njM6Q==}
peerDependencies:
'@layerzerolabs/lz-evm-messagelib-v2': ^2.3.29
@@ -4956,16 +5084,16 @@ packages:
hardhat-deploy: ^0.12.1
solidity-bytes-utils: ^0.8.0
dependencies:
- '@layerzerolabs/lz-evm-messagelib-v2': 2.3.25(@axelar-network/axelar-gmp-sdk-solidity@5.9.0)(@chainlink/contracts-ccip@0.7.6)(@eth-optimism/contracts@0.6.0)(@layerzerolabs/lz-evm-protocol-v2@2.3.25)(@layerzerolabs/lz-evm-v1-0.7@2.3.29)(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2)
- '@layerzerolabs/lz-evm-protocol-v2': 2.3.25(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2)
- '@layerzerolabs/lz-evm-v1-0.7': 2.3.29(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.4)
- '@openzeppelin/contracts': 5.0.2
- '@openzeppelin/contracts-upgradeable': 5.0.2(@openzeppelin/contracts@5.0.2)
+ '@layerzerolabs/lz-evm-messagelib-v2': 2.3.29(@axelar-network/axelar-gmp-sdk-solidity@5.9.0)(@chainlink/contracts-ccip@0.7.6)(@eth-optimism/contracts@0.6.0)(@layerzerolabs/lz-evm-protocol-v2@2.3.29)(@layerzerolabs/lz-evm-v1-0.7@2.3.29)(@openzeppelin/contracts-upgradeable@4.9.5)(@openzeppelin/contracts@4.9.5)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2)
+ '@layerzerolabs/lz-evm-protocol-v2': 2.3.29(@openzeppelin/contracts-upgradeable@4.9.5)(@openzeppelin/contracts@4.9.5)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2)
+ '@layerzerolabs/lz-evm-v1-0.7': 2.3.29(@openzeppelin/contracts-upgradeable@4.9.5)(@openzeppelin/contracts@4.9.5)(hardhat-deploy@0.12.4)
+ '@openzeppelin/contracts': 4.9.5
+ '@openzeppelin/contracts-upgradeable': 4.9.5
hardhat-deploy: 0.12.4
solidity-bytes-utils: 0.8.2
dev: true
- /@layerzerolabs/lz-evm-oapp-v2@2.3.29(@layerzerolabs/lz-evm-messagelib-v2@2.3.29)(@layerzerolabs/lz-evm-protocol-v2@2.3.29)(@layerzerolabs/lz-evm-v1-0.7@2.3.29)(@openzeppelin/contracts-upgradeable@4.9.5)(@openzeppelin/contracts@4.9.5)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2):
+ /@layerzerolabs/lz-evm-oapp-v2@2.3.29(@layerzerolabs/lz-evm-messagelib-v2@2.3.29)(@layerzerolabs/lz-evm-protocol-v2@2.3.29)(@layerzerolabs/lz-evm-v1-0.7@2.3.29)(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2):
resolution: {integrity: sha512-HFuHVCUjZNOjKuhRDBbK2NSGA7sMwFhXRqy0veym9kECDwtHdazLfYmOGhu1amRfomc+eq+KBakJl2XI8njM6Q==}
peerDependencies:
'@layerzerolabs/lz-evm-messagelib-v2': ^2.3.29
@@ -4976,11 +5104,11 @@ packages:
hardhat-deploy: ^0.12.1
solidity-bytes-utils: ^0.8.0
dependencies:
- '@layerzerolabs/lz-evm-messagelib-v2': 2.3.29(@axelar-network/axelar-gmp-sdk-solidity@5.9.0)(@chainlink/contracts-ccip@0.7.6)(@eth-optimism/contracts@0.6.0)(@layerzerolabs/lz-evm-protocol-v2@2.3.29)(@layerzerolabs/lz-evm-v1-0.7@2.3.29)(@openzeppelin/contracts-upgradeable@4.9.5)(@openzeppelin/contracts@4.9.5)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2)
- '@layerzerolabs/lz-evm-protocol-v2': 2.3.29(@openzeppelin/contracts-upgradeable@4.9.5)(@openzeppelin/contracts@4.9.5)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2)
- '@layerzerolabs/lz-evm-v1-0.7': 2.3.29(@openzeppelin/contracts-upgradeable@4.9.5)(@openzeppelin/contracts@4.9.5)(hardhat-deploy@0.12.4)
- '@openzeppelin/contracts': 4.9.5
- '@openzeppelin/contracts-upgradeable': 4.9.5
+ '@layerzerolabs/lz-evm-messagelib-v2': 2.3.29(@axelar-network/axelar-gmp-sdk-solidity@5.9.0)(@chainlink/contracts-ccip@0.7.6)(@eth-optimism/contracts@0.6.0)(@layerzerolabs/lz-evm-protocol-v2@2.3.29)(@layerzerolabs/lz-evm-v1-0.7@2.3.29)(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2)
+ '@layerzerolabs/lz-evm-protocol-v2': 2.3.29(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2)
+ '@layerzerolabs/lz-evm-v1-0.7': 2.3.29(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.4)
+ '@openzeppelin/contracts': 5.0.2
+ '@openzeppelin/contracts-upgradeable': 5.0.2(@openzeppelin/contracts@5.0.2)
hardhat-deploy: 0.12.4
solidity-bytes-utils: 0.8.2
dev: true
@@ -5069,6 +5197,20 @@ packages:
solidity-bytes-utils: 0.8.2
dev: true
+ /@layerzerolabs/lz-evm-protocol-v2@2.3.29(@openzeppelin/contracts-upgradeable@5.0.2)(@openzeppelin/contracts@5.0.2)(hardhat-deploy@0.12.4)(solidity-bytes-utils@0.8.2):
+ resolution: {integrity: sha512-jPQxMkgT88JaJ6zH0PJft1b4nCKe06g0ejWTKtNniSgsgd2qd8Xou6NSmg4tNgZljCfi8SrqWhX7Iz4WIQb2gg==}
+ peerDependencies:
+ '@openzeppelin/contracts': ^4.8.1 || ^5.0.0
+ '@openzeppelin/contracts-upgradeable': ^4.8.1 || ^5.0.0
+ hardhat-deploy: ^0.12.1
+ solidity-bytes-utils: ^0.8.0
+ dependencies:
+ '@openzeppelin/contracts': 5.0.2
+ '@openzeppelin/contracts-upgradeable': 5.0.2(@openzeppelin/contracts@5.0.2)
+ hardhat-deploy: 0.12.4
+ solidity-bytes-utils: 0.8.2
+ dev: true
+
/@layerzerolabs/lz-evm-sdk-v1@2.3.25:
resolution: {integrity: sha512-UJRKkoVh64aWcgLrojkYaZnhb/UETsF8Ea1fqr8GcE+XgGtlwErVLyB0DsXj3mbsq41+/k1/V4wCHDsZMZpQBw==}
dependencies:
@@ -5221,6 +5363,14 @@ packages:
- typescript
dev: true
+ /@layerzerolabs/solhint-config@2.3.3(typescript@5.5.3):
+ resolution: {integrity: sha512-sL2W+kbZRPFKnLDn8A5hQX796gFi8sEVJFRkQbbpFrtB/KGCPpWK/w8JjU7OoOzOvJF9pQnJGS1ayUjDJKCb0Q==}
+ dependencies:
+ solhint: 4.1.1(typescript@5.5.3)
+ transitivePeerDependencies:
+ - typescript
+ dev: true
+
/@layerzerolabs/typescript-config-next@2.3.29:
resolution: {integrity: sha512-YA4znUBa7RFG14NRpSTqLxTxSmtgD5n7k25GcRV1orQI3x5QykNycMbWYgLyWneOexe4h8Pdsq1zpVMuTlllFQ==}
dev: true
@@ -5228,7 +5378,7 @@ packages:
/@manypkg/find-root@1.1.0:
resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==}
dependencies:
- '@babel/runtime': 7.24.8
+ '@babel/runtime': 7.23.8
'@types/node': 12.20.55
find-up: 4.1.0
fs-extra: 8.1.0
@@ -6434,12 +6584,12 @@ packages:
'@typescript-eslint/type-utils': 7.7.1(eslint@8.57.0)(typescript@5.3.3)
'@typescript-eslint/utils': 7.7.1(eslint@8.57.0)(typescript@5.3.3)
'@typescript-eslint/visitor-keys': 7.7.1
- debug: 4.3.4(supports-color@8.1.1)
+ debug: 4.3.5
eslint: 8.57.0
graphemer: 1.4.0
ignore: 5.3.1
natural-compare: 1.4.0
- semver: 7.6.0
+ semver: 7.6.2
ts-api-utils: 1.3.0(typescript@5.3.3)
typescript: 5.3.3
transitivePeerDependencies:
@@ -6463,18 +6613,47 @@ packages:
'@typescript-eslint/type-utils': 7.7.1(eslint@8.57.0)(typescript@5.4.5)
'@typescript-eslint/utils': 7.7.1(eslint@8.57.0)(typescript@5.4.5)
'@typescript-eslint/visitor-keys': 7.7.1
- debug: 4.3.4(supports-color@8.1.1)
+ debug: 4.3.5
eslint: 8.57.0
graphemer: 1.4.0
ignore: 5.3.1
natural-compare: 1.4.0
- semver: 7.6.0
+ semver: 7.6.2
ts-api-utils: 1.3.0(typescript@5.4.5)
typescript: 5.4.5
transitivePeerDependencies:
- supports-color
dev: true
+ /@typescript-eslint/eslint-plugin@7.7.1(@typescript-eslint/parser@7.7.1)(eslint@8.57.0)(typescript@5.5.3):
+ resolution: {integrity: sha512-KwfdWXJBOviaBVhxO3p5TJiLpNuh2iyXyjmWN0f1nU87pwyvfS0EmjC6ukQVYVFJd/K1+0NWGPDXiyEyQorn0Q==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+ peerDependencies:
+ '@typescript-eslint/parser': ^7.0.0
+ eslint: ^8.56.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@eslint-community/regexpp': 4.10.0
+ '@typescript-eslint/parser': 7.7.1(eslint@8.57.0)(typescript@5.5.3)
+ '@typescript-eslint/scope-manager': 7.7.1
+ '@typescript-eslint/type-utils': 7.7.1(eslint@8.57.0)(typescript@5.5.3)
+ '@typescript-eslint/utils': 7.7.1(eslint@8.57.0)(typescript@5.5.3)
+ '@typescript-eslint/visitor-keys': 7.7.1
+ debug: 4.3.5
+ eslint: 8.57.0
+ graphemer: 1.4.0
+ ignore: 5.3.1
+ natural-compare: 1.4.0
+ semver: 7.6.2
+ ts-api-utils: 1.3.0(typescript@5.5.3)
+ typescript: 5.5.3
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.5.3):
resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==}
engines: {node: ^16.0.0 || >=18.0.0}
@@ -6510,7 +6689,7 @@ packages:
'@typescript-eslint/types': 7.7.1
'@typescript-eslint/typescript-estree': 7.7.1(typescript@5.3.3)
'@typescript-eslint/visitor-keys': 7.7.1
- debug: 4.3.4(supports-color@8.1.1)
+ debug: 4.3.5
eslint: 8.57.0
typescript: 5.3.3
transitivePeerDependencies:
@@ -6531,13 +6710,34 @@ packages:
'@typescript-eslint/types': 7.7.1
'@typescript-eslint/typescript-estree': 7.7.1(typescript@5.4.5)
'@typescript-eslint/visitor-keys': 7.7.1
- debug: 4.3.4(supports-color@8.1.1)
+ debug: 4.3.5
eslint: 8.57.0
typescript: 5.4.5
transitivePeerDependencies:
- supports-color
dev: true
+ /@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.3):
+ resolution: {integrity: sha512-vmPzBOOtz48F6JAGVS/kZYk4EkXao6iGrD838sp1w3NQQC0W8ry/q641KU4PrG7AKNAf56NOcR8GOpH8l9FPCw==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+ peerDependencies:
+ eslint: ^8.56.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/scope-manager': 7.7.1
+ '@typescript-eslint/types': 7.7.1
+ '@typescript-eslint/typescript-estree': 7.7.1(typescript@5.5.3)
+ '@typescript-eslint/visitor-keys': 7.7.1
+ debug: 4.3.5
+ eslint: 8.57.0
+ typescript: 5.5.3
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/@typescript-eslint/scope-manager@5.62.0:
resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -6622,6 +6822,26 @@ packages:
- supports-color
dev: true
+ /@typescript-eslint/type-utils@7.7.1(eslint@8.57.0)(typescript@5.5.3):
+ resolution: {integrity: sha512-ZksJLW3WF7o75zaBPScdW1Gbkwhd/lyeXGf1kQCxJaOeITscoSl0MjynVvCzuV5boUz/3fOI06Lz8La55mu29Q==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+ peerDependencies:
+ eslint: ^8.56.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/typescript-estree': 7.7.1(typescript@5.5.3)
+ '@typescript-eslint/utils': 7.7.1(eslint@8.57.0)(typescript@5.5.3)
+ debug: 4.3.4(supports-color@8.1.1)
+ eslint: 8.57.0
+ ts-api-utils: 1.3.0(typescript@5.5.3)
+ typescript: 5.5.3
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/@typescript-eslint/types@5.62.0:
resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -6669,7 +6889,7 @@ packages:
dependencies:
'@typescript-eslint/types': 5.62.0
'@typescript-eslint/visitor-keys': 5.62.0
- debug: 4.3.4(supports-color@8.1.1)
+ debug: 4.3.5
globby: 11.1.0
is-glob: 4.0.3
semver: 7.6.2
@@ -6690,7 +6910,7 @@ packages:
dependencies:
'@typescript-eslint/types': 5.62.0
'@typescript-eslint/visitor-keys': 5.62.0
- debug: 4.3.4(supports-color@8.1.1)
+ debug: 4.3.5
globby: 11.1.0
is-glob: 4.0.3
semver: 7.6.2
@@ -6766,6 +6986,28 @@ packages:
- supports-color
dev: true
+ /@typescript-eslint/typescript-estree@7.7.1(typescript@5.5.3):
+ resolution: {integrity: sha512-CXe0JHCXru8Fa36dteXqmH2YxngKJjkQLjxzoj6LYwzZ7qZvgsLSc+eqItCrqIop8Vl2UKoAi0StVWu97FQZIQ==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/types': 7.7.1
+ '@typescript-eslint/visitor-keys': 7.7.1
+ debug: 4.3.4(supports-color@8.1.1)
+ globby: 11.1.0
+ is-glob: 4.0.3
+ minimatch: 9.0.4
+ semver: 7.6.2
+ ts-api-utils: 1.3.0(typescript@5.5.3)
+ typescript: 5.5.3
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/@typescript-eslint/utils@5.62.0(eslint@8.56.0)(typescript@5.5.3):
resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -6774,13 +7016,13 @@ packages:
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0)
'@types/json-schema': 7.0.15
- '@types/semver': 7.5.6
+ '@types/semver': 7.5.8
'@typescript-eslint/scope-manager': 5.62.0
'@typescript-eslint/types': 5.62.0
'@typescript-eslint/typescript-estree': 5.62.0(typescript@5.5.3)
eslint: 8.56.0
eslint-scope: 5.1.1
- semver: 7.5.4
+ semver: 7.6.2
transitivePeerDependencies:
- supports-color
- typescript
@@ -6814,13 +7056,33 @@ packages:
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
'@types/json-schema': 7.0.15
- '@types/semver': 7.5.6
+ '@types/semver': 7.5.8
'@typescript-eslint/scope-manager': 5.62.0
'@typescript-eslint/types': 5.62.0
'@typescript-eslint/typescript-estree': 5.62.0(typescript@5.4.5)
eslint: 8.57.0
eslint-scope: 5.1.1
- semver: 7.5.4
+ semver: 7.6.2
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
+ dev: true
+
+ /@typescript-eslint/utils@5.62.0(eslint@8.57.0)(typescript@5.5.3):
+ resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
+ dependencies:
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
+ '@types/json-schema': 7.0.15
+ '@types/semver': 7.5.8
+ '@typescript-eslint/scope-manager': 5.62.0
+ '@typescript-eslint/types': 5.62.0
+ '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.5.3)
+ eslint: 8.57.0
+ eslint-scope: 5.1.1
+ semver: 7.6.2
transitivePeerDependencies:
- supports-color
- typescript
@@ -6883,6 +7145,25 @@ packages:
- typescript
dev: true
+ /@typescript-eslint/utils@7.7.1(eslint@8.57.0)(typescript@5.5.3):
+ resolution: {integrity: sha512-QUvBxPEaBXf41ZBbaidKICgVL8Hin0p6prQDu6bbetWo39BKbWJxRsErOzMNT1rXvTll+J7ChrbmMCXM9rsvOQ==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+ peerDependencies:
+ eslint: ^8.56.0
+ dependencies:
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
+ '@types/json-schema': 7.0.15
+ '@types/semver': 7.5.8
+ '@typescript-eslint/scope-manager': 7.7.1
+ '@typescript-eslint/types': 7.7.1
+ '@typescript-eslint/typescript-estree': 7.7.1(typescript@5.5.3)
+ eslint: 8.57.0
+ semver: 7.6.2
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
+ dev: true
+
/@typescript-eslint/visitor-keys@5.62.0:
resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -8120,6 +8401,22 @@ packages:
typescript: 5.4.5
dev: true
+ /cosmiconfig@8.3.6(typescript@5.5.3):
+ resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ typescript: '>=4.9.5'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ import-fresh: 3.3.0
+ js-yaml: 4.1.0
+ parse-json: 5.2.0
+ path-type: 4.0.0
+ typescript: 5.5.3
+ dev: true
+
/crc-32@1.2.2:
resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==}
engines: {node: '>=0.8'}
@@ -8845,7 +9142,7 @@ packages:
eslint: '*'
eslint-plugin-import: '*'
dependencies:
- debug: 4.3.4(supports-color@8.1.1)
+ debug: 4.3.5
enhanced-resolve: 5.16.0
eslint: 8.57.0
eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.7.1)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
@@ -9039,6 +9336,19 @@ packages:
- typescript
dev: true
+ /eslint-plugin-jest-extended@2.0.0(eslint@8.57.0)(typescript@5.5.3):
+ resolution: {integrity: sha512-nMhVVsVcG/+Q6FMshql35WBxwx8xlBhxKgAG08WP3BYWfXrp28oxLpJVu9JSbMpfmfKGVrHwMYJGfPLRKlGB8w==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ peerDependencies:
+ eslint: ^7.0.0 || ^8.0.0
+ dependencies:
+ '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.5.3)
+ eslint: 8.57.0
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
+ dev: true
+
/eslint-plugin-jest@27.6.3(@typescript-eslint/eslint-plugin@6.21.0)(eslint@8.56.0)(typescript@5.5.3):
resolution: {integrity: sha512-+YsJFVH6R+tOiO3gCJon5oqn4KWc+mDq2leudk8mrp8RFubLOo9CVyi3cib4L7XMpxExmkmBZQTPDYVBzgpgOA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -9305,7 +9615,7 @@ packages:
ajv: 6.12.6
chalk: 4.1.2
cross-spawn: 7.0.3
- debug: 4.3.4(supports-color@8.1.1)
+ debug: 4.3.5
doctrine: 3.0.0
escape-string-regexp: 4.0.0
eslint-scope: 7.2.2
@@ -9533,7 +9843,6 @@ packages:
dependencies:
is-hex-prefixed: 1.0.0
strip-hex-prefix: 1.0.0
- bundledDependencies: false
/eventemitter3@3.1.2:
resolution: {integrity: sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==}
@@ -9836,6 +10145,7 @@ packages:
optional: true
dependencies:
debug: 4.3.4(supports-color@8.1.1)
+ dev: true
/follow-redirects@1.15.5(debug@4.3.5):
resolution: {integrity: sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==}
@@ -9859,7 +10169,6 @@ packages:
optional: true
dependencies:
debug: 4.3.5
- dev: true
/for-each@0.3.3:
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
@@ -10496,7 +10805,7 @@ packages:
chalk: 2.4.2
chokidar: 3.6.0
ci-info: 2.0.0
- debug: 4.3.4(supports-color@8.1.1)
+ debug: 4.3.5
enquirer: 2.4.1
env-paths: 2.2.1
ethereum-cryptography: 1.2.0
@@ -10515,7 +10824,7 @@ packages:
raw-body: 2.5.2
resolve: 1.17.0
semver: 6.3.1
- solc: 0.7.3(debug@4.3.4)
+ solc: 0.7.3(debug@4.3.5)
source-map-support: 0.5.21
stacktrace-parser: 0.1.10
ts-node: 10.9.2(@swc/core@1.4.0)(@types/node@18.18.14)(typescript@5.3.3)
@@ -10559,7 +10868,7 @@ packages:
chalk: 2.4.2
chokidar: 3.6.0
ci-info: 2.0.0
- debug: 4.3.4(supports-color@8.1.1)
+ debug: 4.3.5
enquirer: 2.4.1
env-paths: 2.2.1
ethereum-cryptography: 1.2.0
@@ -10578,7 +10887,7 @@ packages:
raw-body: 2.5.2
resolve: 1.17.0
semver: 6.3.1
- solc: 0.7.3(debug@4.3.4)
+ solc: 0.7.3(debug@4.3.5)
source-map-support: 0.5.21
stacktrace-parser: 0.1.10
ts-node: 10.9.2(@types/node@18.18.14)(typescript@5.4.2)
@@ -10623,7 +10932,7 @@ packages:
chalk: 2.4.2
chokidar: 3.6.0
ci-info: 2.0.0
- debug: 4.3.4(supports-color@8.1.1)
+ debug: 4.3.5
enquirer: 2.4.1
env-paths: 2.2.1
ethereum-cryptography: 1.2.0
@@ -10642,7 +10951,7 @@ packages:
raw-body: 2.5.2
resolve: 1.17.0
semver: 6.3.1
- solc: 0.7.3(debug@4.3.4)
+ solc: 0.7.3(debug@4.3.5)
source-map-support: 0.5.21
stacktrace-parser: 0.1.10
ts-node: 10.9.2(@types/node@18.18.14)(typescript@5.4.5)
@@ -10687,7 +10996,7 @@ packages:
chalk: 2.4.2
chokidar: 3.6.0
ci-info: 2.0.0
- debug: 4.3.4(supports-color@8.1.1)
+ debug: 4.3.5
enquirer: 2.4.1
env-paths: 2.2.1
ethereum-cryptography: 1.2.0
@@ -10706,7 +11015,7 @@ packages:
raw-body: 2.5.2
resolve: 1.17.0
semver: 6.3.1
- solc: 0.7.3(debug@4.3.4)
+ solc: 0.7.3(debug@4.3.5)
source-map-support: 0.5.21
stacktrace-parser: 0.1.10
ts-node: 10.9.2(@swc/core@1.4.0)(@types/node@18.18.14)(typescript@5.5.3)
@@ -10751,7 +11060,7 @@ packages:
chalk: 2.4.2
chokidar: 3.6.0
ci-info: 2.0.0
- debug: 4.3.4(supports-color@8.1.1)
+ debug: 4.3.5
enquirer: 2.4.1
env-paths: 2.2.1
ethereum-cryptography: 1.2.0
@@ -10770,7 +11079,7 @@ packages:
raw-body: 2.5.2
resolve: 1.17.0
semver: 6.3.1
- solc: 0.7.3(debug@4.3.4)
+ solc: 0.7.3(debug@4.3.5)
source-map-support: 0.5.21
stacktrace-parser: 0.1.10
tsort: 0.0.1
@@ -14096,14 +14405,14 @@ packages:
yargs: 15.4.1
dev: true
- /solc@0.7.3(debug@4.3.4):
+ /solc@0.7.3(debug@4.3.5):
resolution: {integrity: sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==}
engines: {node: '>=8.0.0'}
hasBin: true
dependencies:
command-exists: 1.2.9
commander: 3.0.2
- follow-redirects: 1.15.5(debug@4.3.4)
+ follow-redirects: 1.15.6(debug@4.3.5)
fs-extra: 0.30.0
js-sha3: 0.8.0
memorystream: 0.3.1
@@ -14147,7 +14456,7 @@ packages:
latest-version: 7.0.0
lodash: 4.17.21
pluralize: 8.0.0
- semver: 7.6.0
+ semver: 7.6.2
strip-ansi: 6.0.1
table: 6.8.2
text-table: 0.2.0
@@ -14175,7 +14484,35 @@ packages:
latest-version: 7.0.0
lodash: 4.17.21
pluralize: 8.0.0
- semver: 7.6.0
+ semver: 7.6.2
+ strip-ansi: 6.0.1
+ table: 6.8.2
+ text-table: 0.2.0
+ optionalDependencies:
+ prettier: 2.8.8
+ transitivePeerDependencies:
+ - typescript
+ dev: true
+
+ /solhint@4.1.1(typescript@5.5.3):
+ resolution: {integrity: sha512-7G4iF8H5hKHc0tR+/uyZesSKtfppFIMvPSW+Ku6MSL25oVRuyFeqNhOsXHfkex64wYJyXs4fe+pvhB069I19Tw==}
+ hasBin: true
+ dependencies:
+ '@solidity-parser/parser': 0.16.2
+ ajv: 6.12.6
+ antlr4: 4.13.1
+ ast-parents: 0.0.1
+ chalk: 4.1.2
+ commander: 10.0.1
+ cosmiconfig: 8.3.6(typescript@5.5.3)
+ fast-diff: 1.3.0
+ glob: 8.1.0
+ ignore: 5.3.1
+ js-yaml: 4.1.0
+ latest-version: 7.0.0
+ lodash: 4.17.21
+ pluralize: 8.0.0
+ semver: 7.6.2
strip-ansi: 6.0.1
table: 6.8.2
text-table: 0.2.0
@@ -14733,7 +15070,7 @@ packages:
/tronweb@5.3.2(debug@4.3.5):
resolution: {integrity: sha512-iPcIjMCxb6H7FXMntAj47F3L+7jSideyQ7ZOvRj9MeZBh46SHevMrDDR57HzakUa/tT8VvlPFHtqFK4hzTLkXw==}
dependencies:
- '@babel/runtime': 7.23.8
+ '@babel/runtime': 7.24.8
'@ethersproject/abi': 5.7.0
'@tronweb3/google-protobuf': 3.21.2
axios: 1.7.2(debug@4.3.5)
@@ -14788,6 +15125,15 @@ packages:
typescript: 5.4.5
dev: true
+ /ts-api-utils@1.3.0(typescript@5.5.3):
+ resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==}
+ engines: {node: '>=16'}
+ peerDependencies:
+ typescript: '>=4.2.0'
+ dependencies:
+ typescript: 5.5.3
+ dev: true
+
/ts-command-line-args@2.5.1:
resolution: {integrity: sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==}
hasBin: true
diff --git a/tests-user/tests/create-lz-oapp.bats b/tests-user/tests/create-lz-oapp.bats
index df447a1e4..02c42d5ee 100644
--- a/tests-user/tests/create-lz-oapp.bats
+++ b/tests-user/tests/create-lz-oapp.bats
@@ -147,6 +147,17 @@ teardown() {
pnpm lint:fix
}
+@test "should work with pnpm & oft-adapter example in CI mode" {
+ local DESTINATION="$PROJECTS_DIRECTORY/pnpm-oft-adapter"
+
+ npx --yes create-lz-oapp --ci --example oft-adapter --destination $DESTINATION --package-manager pnpm
+ cd "$DESTINATION"
+ pnpm compile
+ pnpm test
+ pnpm lint
+ pnpm lint:fix
+}
+
@test "should work with yarn & oapp example in CI mode" {
local DESTINATION="$PROJECTS_DIRECTORY/yarn-oapp"
@@ -180,6 +191,17 @@ teardown() {
yarn lint:fix
}
+@test "should work with yarn & oft-adapter example in CI mode" {
+ local DESTINATION="$PROJECTS_DIRECTORY/yarn-oapp"
+
+ npx --yes create-lz-oapp --ci --example oft-adapter --destination $DESTINATION --package-manager yarn
+ cd "$DESTINATION"
+ yarn compile
+ yarn test
+ yarn lint
+ yarn lint:fix
+}
+
@test "should work with npm & oapp example in CI mode" {
local DESTINATION="$PROJECTS_DIRECTORY/npm-oapp"
@@ -212,3 +234,14 @@ teardown() {
npm run lint
npm run lint:fix
}
+
+@test "should work with npm & oft-adapter example in CI mode" {
+ local DESTINATION="$PROJECTS_DIRECTORY/npm-oft"
+
+ npx --yes create-lz-oapp --ci --example oft-adapter --destination $DESTINATION --package-manager npm
+ cd "$DESTINATION"
+ npm run compile
+ npm run test
+ npm run lint
+ npm run lint:fix
+}