Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/flat-bears-doubt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@layerzerolabs/oft-example": minor
---

Adds a normalized send script that can be extended for other VMs
5 changes: 5 additions & 0 deletions .changeset/orange-sheep-provide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@layerzerolabs/mint-burn-oft-adapter-example": minor
---

Adds a send script and simple config to the MABA example
5 changes: 5 additions & 0 deletions .changeset/tricky-spies-dream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@layerzerolabs/oft-adapter-example": minor
---

Adds send task to oft-adapter
1 change: 1 addition & 0 deletions examples/mint-burn-oft-adapter/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ module.exports = {
// @layerzerolabs/eslint-config-next defines rules for turborepo-based projects
// that are not relevant for this particular project
'turbo/no-undeclared-env-vars': 'off',
'import/no-unresolved': 'warn', // Updated to warn to avoid erratic popping up of this particular error for '@layerzerolabs/metadata-tools' even when the package has been installed correctly
},
};
49 changes: 49 additions & 0 deletions examples/mint-burn-oft-adapter/deploy/MintBurnERC20Mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import assert from 'assert'

import { type DeployFunction } from 'hardhat-deploy/types'

const contractName = 'MintBurnERC20Mock'

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}`)

// Token configuration
const tokenName = 'Mock Mint Burn Token'
const tokenSymbol = 'MMBT'
const initialMintAmount = hre.ethers.utils.parseEther('1000000') // 1M tokens

const { address } = await deploy(contractName, {
from: deployer,
args: [
tokenName, // Token name
tokenSymbol, // Token symbol
],
log: true,
skipIfAlreadyDeployed: false,
})

console.log(`Deployed contract: ${contractName}, network: ${hre.network.name}, address: ${address}`)
console.log(`Token: ${tokenName} (${tokenSymbol})`)

// Mint initial tokens to the deployer
const [signer] = await hre.ethers.getSigners()
const mintBurnToken = await hre.ethers.getContractAt(contractName, address, signer)

const mintTx = await mintBurnToken.mint(deployer, initialMintAmount)
await mintTx.wait()

const balance = await mintBurnToken.balanceOf(deployer)
console.log(`Minted ${hre.ethers.utils.formatEther(balance)} ${tokenSymbol} tokens to deployer: ${deployer}`)
}

deploy.tags = [contractName]

export default deploy
20 changes: 14 additions & 6 deletions examples/mint-burn-oft-adapter/hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import { EndpointId } from '@layerzerolabs/lz-definitions'

import './type-extensions'

import './tasks/sendOFT'

// Set your preferred authentication method
//
// If you prefer using a mnemonic, set a MNEMONIC environment variable
Expand Down Expand Up @@ -54,9 +56,9 @@ const config: HardhatUserConfig = {
],
},
networks: {
'sepolia-testnet': {
eid: EndpointId.SEPOLIA_V2_TESTNET,
url: process.env.RPC_URL_SEPOLIA || 'https://rpc.sepolia.org/',
'optimism-testnet': {
eid: EndpointId.OPTSEP_V2_TESTNET,
url: process.env.RPC_URL_OP_SEPOLIA || 'https://optimism-sepolia.gateway.tenderly.co',
accounts,
oftAdapter: {
tokenAddress: '0x0', // Set the token address for the OFT adapter
Expand All @@ -66,11 +68,17 @@ const config: HardhatUserConfig = {
eid: EndpointId.AVALANCHE_V2_TESTNET,
url: process.env.RPC_URL_FUJI || 'https://rpc.ankr.com/avalanche_fuji',
accounts,
oftAdapter: {
tokenAddress: '0x0', // Set the token address for the OFT adapter
},
},
'amoy-testnet': {
eid: EndpointId.AMOY_V2_TESTNET,
url: process.env.RPC_URL_AMOY || 'https://polygon-amoy-bor-rpc.publicnode.com',
'arbitrum-testnet': {
eid: EndpointId.ARBSEP_V2_TESTNET,
url: process.env.RPC_URL_ARB_SEPOLIA || 'https://arbitrum-sepolia.gateway.tenderly.co',
accounts,
oftAdapter: {
tokenAddress: '0x0', // Set the token address for the OFT adapter
},
},
hardhat: {
// Need this for testing because TestHelperOz5.sol is exceeding the compiled contract size limit
Expand Down
116 changes: 57 additions & 59 deletions examples/mint-burn-oft-adapter/layerzero.config.ts
Original file line number Diff line number Diff line change
@@ -1,75 +1,73 @@
import { EndpointId } from '@layerzerolabs/lz-definitions'
import { ExecutorOptionType } from '@layerzerolabs/lz-v2-utilities'
import { TwoWayConfig, generateConnectionsConfig } from '@layerzerolabs/metadata-tools'
import { OAppEnforcedOption } from '@layerzerolabs/toolbox-hardhat'

import type { OAppOmniGraphHardhat, OmniPointHardhat } from '@layerzerolabs/toolbox-hardhat'
import type { 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,
* oftAdapter: {
* tokenAddress: '0x0', // Set the token address for the OFT adapter
* },
* },
*/
const sepoliaContract: OmniPointHardhat = {
eid: EndpointId.SEPOLIA_V2_TESTNET,
const optimismContract: OmniPointHardhat = {
eid: EndpointId.OPTSEP_V2_TESTNET,
contractName: 'MyMintBurnOFTAdapter',
}

const fujiContract: OmniPointHardhat = {
const avalancheContract: OmniPointHardhat = {
eid: EndpointId.AVALANCHE_V2_TESTNET,
contractName: 'MyOFT',
}

const amoyContract: OmniPointHardhat = {
eid: EndpointId.AMOY_V2_TESTNET,
const arbitrumContract: OmniPointHardhat = {
eid: EndpointId.ARBSEP_V2_TESTNET,
contractName: 'MyOFT',
}

const config: OAppOmniGraphHardhat = {
contracts: [
{
contract: fujiContract,
},
{
contract: sepoliaContract,
},
{
contract: amoyContract,
},
// To connect all the above chains to each other, we need the following pathways:
// Optimism <-> Avalanche
// Optimism <-> Arbitrum
// Avalanche <-> Arbitrum

// For this example's simplicity, we will use the same enforced options values for sending to all chains
// For production, you should ensure `gas` is set to the correct value through profiling the gas usage of calling OFT._lzReceive(...) on the destination chain
// To learn more, read https://docs.layerzero.network/v2/concepts/applications/oapp-standard#execution-options-and-enforced-settings
const EVM_ENFORCED_OPTIONS: OAppEnforcedOption[] = [
{
msgType: 1,
optionType: ExecutorOptionType.LZ_RECEIVE,
gas: 80000,
value: 0,
},
]

// With the config generator, pathways declared are automatically bidirectional
// i.e. if you declare A,B there's no need to declare B,A
const pathways: TwoWayConfig[] = [
[
optimismContract, // Chain A contract
avalancheContract, // Chain B contract
[['LayerZero Labs'], []], // [ requiredDVN[], [ optionalDVN[], threshold ] ]
[1, 1], // [A to B confirmations, B to A confirmations]
[EVM_ENFORCED_OPTIONS, EVM_ENFORCED_OPTIONS], // Chain B enforcedOptions, Chain A enforcedOptions
],
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,
},
[
optimismContract, // Chain A contract
arbitrumContract, // Chain C contract
[['LayerZero Labs'], []], // [ requiredDVN[], [ optionalDVN[], threshold ] ]
[1, 1], // [A to B confirmations, B to A confirmations]
[EVM_ENFORCED_OPTIONS, EVM_ENFORCED_OPTIONS], // Chain C enforcedOptions, Chain A enforcedOptions
],
}
[
avalancheContract, // Chain B contract
arbitrumContract, // Chain C contract
[['LayerZero Labs'], []], // [ requiredDVN[], [ optionalDVN[], threshold ] ]
[1, 1], // [A to B confirmations, B to A confirmations]
[EVM_ENFORCED_OPTIONS, EVM_ENFORCED_OPTIONS], // Chain C enforcedOptions, Chain B enforcedOptions
],
]

export default config
export default async function () {
// Generate the connections config based on the pathways
const connections = await generateConnectionsConfig(pathways)
return {
contracts: [{ contract: optimismContract }, { contract: avalancheContract }, { contract: arbitrumContract }],
connections,
}
}
3 changes: 3 additions & 0 deletions examples/mint-burn-oft-adapter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@
},
"devDependencies": {
"@babel/core": "^7.23.9",
"@layerzerolabs/devtools-evm-hardhat": "^3.1.0",
"@layerzerolabs/eslint-config-next": "~2.3.39",
"@layerzerolabs/io-devtools": "~0.2.0",
"@layerzerolabs/lz-definitions": "^3.0.75",
"@layerzerolabs/lz-evm-messagelib-v2": "^3.0.75",
"@layerzerolabs/lz-evm-protocol-v2": "^3.0.75",
"@layerzerolabs/lz-evm-v1-0.7": "^3.0.75",
"@layerzerolabs/lz-v2-utilities": "^3.0.75",
"@layerzerolabs/metadata-tools": "^2.0.0",
"@layerzerolabs/oapp-evm": "^0.3.2",
"@layerzerolabs/oft-evm": "^3.1.3",
"@layerzerolabs/prettier-config-next": "^2.3.39",
Expand Down
Loading