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 @@ +

+ + LayerZero + +

+ +

+ 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 +}