From 67e723f83f33cedf98f9de9c4bcb193a62a8b69e Mon Sep 17 00:00:00 2001 From: Vivek Jain Date: Mon, 3 Jun 2024 18:01:56 +0530 Subject: [PATCH 1/8] Add article to send NFTs across chains --- .../docs/how-tos/send-NFTs-across-chains.md | 311 ++++++++++++++++++ 1 file changed, 311 insertions(+) create mode 100644 docs/build/isc/v1.0.0-rc.6/docs/how-tos/send-NFTs-across-chains.md diff --git a/docs/build/isc/v1.0.0-rc.6/docs/how-tos/send-NFTs-across-chains.md b/docs/build/isc/v1.0.0-rc.6/docs/how-tos/send-NFTs-across-chains.md new file mode 100644 index 00000000000..0ae68a9d500 --- /dev/null +++ b/docs/build/isc/v1.0.0-rc.6/docs/how-tos/send-NFTs-across-chains.md @@ -0,0 +1,311 @@ +# Send NFTs Across Chains + +## Introduction + +[LayerZero ONFT V1FV](https://docs.layerzero.network/V1) enables cross-chain transfers of existing ERC721 tokens. For testing purposes, ShimmerEVM testnet is chosen as the source chain, while the BNB testnet is chosen as the destination chain. + +:::info Community Libs +You can clone the Utilities for LayerZero ONFT V1 from [IOTA Community GitHub Repository](https://github.com/iota-community/layerzero-onft-v1-utils). +::: + +### Why Would a User Need to Send ERC721 Tokens Across Chains? + +By facilitating the movement of ERC721 tokens across chains, users gain flexibility and can optimize their NFT usage according to their specific needs, preferences, and circumstances. + +**Use-case 1** + +To enable the existing erc721 tokens for cross-chain sending, both ProxyONFT contract (on source chain) and ONFT contract (on destination chain) are needed. + +The origin NFT token will be locked in the ProxyONFT so that the ONFT-wrapped tokens will be minted on the destination chain. If the NFT token already exists on the destination chain (this happens when the ONFT-wrapped token on destination chain is sent back to the source chain), no new token minting will happen. Instead, the NFT tokens will be transferred from the ONFT contract to the user wallet address. Relevant code + +**Use-case 2** + +For new erc721 tokens to be launched, ONFT standard can be leveraged to enable cross-chain sending without the need of ProxyONFT. Similarly to the above: lock on source chain and mint or transfer on destination chain. + +**Contracts:** + +- [ProxyONFT721](https://docs.layerzero.network/v1/developers/evm-guides/contract-standards/721#proxyonft721sol) +- [ProxyONFT1155](https://docs.layerzero.network/v1/developers/evm-guides/contract-standards/1155#proxyonft1155sol) +- [ONFT721](https://docs.layerzero.network/v1/developers/evm-guides/contract-standards/721#onft721sol) +- [ONFT1155](https://docs.layerzero.network/v1/developers/evm-guides/contract-standards/1155#onft1155sol) + +## Scripts + +### Deploy ProxyONFT and ONFT contracts + +#### For erc721 + +- MyProxyONFT721.sol: + - CTOR: + - [minGasToTransferAndStore](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/onft721/ONFT721Core.sol#L169): The minimum gas needed to transfer and store your NFT, typically 100k for ERC721. This value would vary depending on your contract complexity, it's recommended to test. If this value is set too low, the destination tx will fail and a manual retry is needed + - lzEndpoint: LayerZero Endpoint on the source chain + - proxyToken: deployed contract address of the NFT tokens on source chain + +- MyONFT721.sol: + - CTOR: + - name: name of the ONFT-wrapped tokens on the destination chain + - symbol: symbol of the ONFT-wrapped tokens on the destination chain + - [minGasToTransferAndStore](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/onft721/ONFT721Core.sol#L169): same as above + - lzEndpoint: - lzEndpoint: LayerZero Endpoint on the destination chain + +### Set trusted remote + +For existing erc721 tokens, both of the ProxyONFT and ONFT contract instances need to be paired with each other. + +For the upcoming erc721 tokens that wanna leverage ONFT standard, the ONFT contract instance on the source chain needs to be paired with another ONFT contract instance on the destination chain. + +This setting is done via the method [setTrustedRemote](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/LzApp.sol#L138) + +### Set min destination gas + +Both of the ProxyONFT contract instance and the ONFT contract instance need to be set for min gas on destination. + +This setting is done via the method [setMinDstGas](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/LzApp.sol#L159) + +Reference of [minGasLimit](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/LzApp.sol#L85C37-L85C48) + +**Notice:** +It is required that `minDstGas` <= `providedGasLimit` which is to be set via `adapterParams` upon cross-chain sending on source chain. + +### Set batch size limit + +Both of the ProxyONFT contract instance and the ONFT contract instance need to be set for batch size limit on source chain to limit the number of tokens to be sent to other chain when using the method [sendBatchFrom](https://github.com/LayerZero-Labs/solidity-examples/blob/c04e7d211b1b610f84761df943e6a38b0a53d304/contracts/token/onft721/ONFT721Core.sol#L67). + +This setting is done via the method [setDstChainIdToBatchLimit](https://github.com/LayerZero-Labs/solidity-examples/blob/c04e7d211b1b610f84761df943e6a38b0a53d304/contracts/token/onft721/ONFT721Core.sol#L194) + +Reference of [dstChainIdToBatchLimit](https://github.com/LayerZero-Labs/solidity-examples/blob/c04e7d211b1b610f84761df943e6a38b0a53d304/contracts/token/onft721/ONFT721Core.sol#L90) + +**Notice:** +Default value is 1 + +### Procedure to send tokens from source chain to destinaion chain and vice versa + +For the existing erc721 tokens that involve with both ProxyONFT contract (on source chain) and ONFT contract (on destination chain), the token sending procedure is as follows: + +1. The sender approves his erc721 tokens for the ProxyONFT contract +2. The sender calls the func `estimateSendFee()` of the ProxyONFT contract to estimate cross-chain fee to be paid in native on the source chain +3. The sender calls the func `sendFrom()` of the ProxyONFT contract to transfer tokens on source chain to destination chain +4. Optional: wait for the tx finalization on destination chain by using the lib [@layerzerolabs/scan-client](https://www.npmjs.com/package/@layerzerolabs/scan-client#example-usage) + +To send back the ONFT-wrapped tokens on destination chain to source chain, the procedure is similar (approve step is also needed) but the operations will be on the ONFT contract. + +**AdapterParams Notice** + +- To set gas drop on destination in `adapterParams`, reference [this](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/libs/LzLib.sol#L44) + + - The provided gas drop must <= the config one. Otherwise, will get error [dstNativeAmt too large](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/mocks/LZEndpointMock.sol#L413) + +- To set default `adapterParams` without gas drop need, reference [this](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/libs/LzLib.sol#L34) + +**Appendix:** + +- [function estimateSendFee()](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/onft721/interfaces/IONFT721Core.sol#L70) +- [function sendFrom()](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/onft721/interfaces/IONFT721Core.sol#L36) +- [@layerzerolabs/scan-client](https://www.npmjs.com/package/@layerzerolabs/scan-client#example-usage) +- [LayerZero Endpoint V1](https://docs.layerzero.network/v1/developers/technical-reference/mainnet/mainnet-addresses) +- [LayerZero explorer](https://testnet.layerzeroscan.com/) + + +### Install the Library + +After you have cloned the [IOTA Community Utilities for LayerZero ONFT V! repository](https://github.com/iota-community/layerzero-onft-v1-utils), you should run the following command to install: + +``` +yarn +``` + +## Compile the Contracts + +If you want to use the standard implementation for ERC20, copy the [`contracts-standard`](https://github.com/iota-community/layerzero-oft-V1-utils/tree/main/contracts-standard) folder to `contracts`. If you want to use a custom implementation, copy the [`contracts-wiota`](https://github.com/iota-community/layerzero-oft-V1-utils/tree/main/contracts-wiota) to `contracts`. Then, run the following command to compile the contracts: + +```bash +yarn compile +``` + +### Set Your Configuration + +You should copy the template [`.env.example`](https://github.com/iota-community/layerzero-oft-V1-utils/blob/main/.env.example) file to a file called `.env`, and edit any of the configuration options you see fit. + +```bash +cp .env.example .env +``` + +### Deploy the Contracts + +## Deploy mock ERC721 + +```bash +yarn deploy-erc721-mock-smr-testnet +``` + +Expected log output : + +```bash +npx hardhat run scripts/deploy_erc721.ts --network shimmerEvmTestnet +Deployed ERC721Mock contract address:0xFddbA8928a763679fb8C99d12541B7c6177e9c3c +Done in 4.49s. +``` + +### Deploy ProxyONFT721 on source chain + +You can use the following command to deploy ProxyONFT721 on source chain (e.g. ShimmerEVM testnet): + +```bash +yarn deploy-proxy-onft-smr-testnet +``` + +Expected log output : + +```bash +npx hardhat run scripts/deploy_proxy_onft721.ts --network shimmerEvmTestnet +Deployed MyProxyONFT721 contract address:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2 +Done in 4.50s. +``` + +### Deploy ProxyONFT721 on destination chain + +You can use the following command to deploy ProxyONFT721 on destination chain (e.g. BNB testnet): + +```bash +yarn set-min-dest-gas-onft-bnb-testnet +``` + +Expected log output : + +```bash +export isForProxy=false && npx hardhat run scripts/set_min_destination_gas.ts --network bnbTestnet +setMinDstGas - isForProxy:false, proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnRemoteChain:10230, minDstGas:150000 +setMinDstGas (packetType 0) tx: 0xce044ded17daa77a8aefc3d39b99c5381216eb4057ddce6253affde6cda2091c +setMinDstGas (packetType 1) tx: 0x3a26ae40ac058099bfd8b85910009a5e5e8b03f16a5f032b572827d48be8f2b0 +Done in 9.34s. +``` + +### Set min destination gas + +You can use the following command to set min destination gas on ProxyONFT (source chain, e.g. ShimmerEVM testnet): + +```bash +yarn set-min-dest-gas-proxy-onft-smr-testnet +``` +Expected log output : + +```bash +export isForProxy=true && npx hardhat run scripts/set_min_destination_gas.ts --network shimmerEvmTestnet +setMinDstGas - isForProxy:true, proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnRemoteChain:10102, minDstGas:150000 +setMinDstGas (packetType 0) tx: 0xcab06e9989448153a4bbc1bb166fc2d33467f3311d1851bf2ff719d982daa613 +setMinDstGas (packetType 1) tx: 0xe78fd3f0bf668fafbc423decd2cf14a27d74543af3ac9daf031f0b278c22ea78 +Done in 6.07s. +``` + +You can use the following command to set min destination gas on ONFT (destination chain, e.g. BNB testnet): + +```bash +yarn set-min-dest-gas-onft-bnb-testnet +``` + +Expected log output : + +```bash +export isForProxy=false && npx hardhat run scripts/set_min_destination_gas.ts --network bnbTestnet +setMinDstGas - isForProxy:false, proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnRemoteChain:10230, minDstGas:150000 +setMinDstGas (packetType 0) tx: 0xce044ded17daa77a8aefc3d39b99c5381216eb4057ddce6253affde6cda2091c +setMinDstGas (packetType 1) tx: 0x3a26ae40ac058099bfd8b85910009a5e5e8b03f16a5f032b572827d48be8f2b0 +Done in 9.34s. +``` + +### Set batch size limit + +You can use the following command to set batch size limits on ProxyONFT (source chain, e.g. ShimmerEVM testnet): + +```bash +yarn set-batch-size-limit-proxy-onft-smr-testnet +``` +Expected log output : + +```bash +export isForProxy=true && npx hardhat run scripts/set_batch_size_limit.ts --network shimmerEvmTestnet +setBatchSizeLimit - isForProxy:true, proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnRemoteChain:10102, batchSizeLimit:1 +setBatchSizeLimit tx: 0x70c23b3d3d5e94ef82e50944f7eba93fa1fe8db3a5487ac371015e7a14482e75 +Done in 4.28s. +``` + +You can use the following command to set batch size limits on ONFT (destination chain, e.g. BNB testnet): + +```bash +yarn set-batch-size-limit-onft-bnb-testnet +``` + +Expected log output : + +```bash +export isForProxy=false && npx hardhat run scripts/set_batch_size_limit.ts --network bnbTestnet +setBatchSizeLimit - isForProxy:false, proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnRemoteChain:10230, batchSizeLimit:1 +setBatchSizeLimit tx: 0x8cb44c2195ac93da552c646677e6585c95ab172df19463637541933ec70dc9b8 +Done in 4.26s. +``` + +### Set trusted remote + +You can use the following command to set trusted remote on ProxyONFT (source chain, e.g. ShimmerEVM testnet): + +```bash +yarn set-remote-proxy-onft-smr-testnet +``` +Expected log output : + +```bash +export isForProxy=true && npx hardhat run scripts/set_trusted_remote.ts --network shimmerEvmTestnet +setTrustedRemote - isForProxy:true, proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnRemoteChain:10102 +setTrustedRemote tx: 0xce52c0f25090ef7c1668ef04ff2f6098551c9f56b3ce881d17181bf106457016 +Done in 4.24s. +``` + +You can use the following command to set trusted remote on ONFT (destination chain, e.g. BNB testnet): + +```bash +yarn set-remote-onft-bnb-testnet +``` + +Expected log output : + +```bash +export isForProxy=false && npx hardhat run scripts/set_trusted_remote.ts --network bnbTestnet +setTrustedRemote - isForProxy:false, proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnRemoteChain:10230 +setTrustedRemote tx: 0x311a0568b5afce7d601df2613f8ff80428d8a4d2f2c91012e0e4a8cbc0aedf59 +Done in 4.88s. +``` + +### Send origin tokens from source chain to destinaion chain + +```bash +yarn send-onft-from-smr-testnet +``` + +Expected log output: +```bash +npx hardhat run scripts/send_onft.ts --network shimmerEvmTestnet +sendONFT - proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnSrcChain:10230, lzEndpointIdOnDestChain:10102, gasDropInWeiOnDestChain:0, providedGasLimit:200000, receivingAccountAddress:0x5e812d3128D8fD7CEac08CEca1Cd879E76a6E028, sender: 0x57A4bD139Fb673D364A6f12Df9177A3f686625F3, nftTokenId:2, nftTokenAddress:0xFddbA8928a763679fb8C99d12541B7c6177e9c3c +sendONFT - approve tx: 0xa871bc79e45bf20f33c626044d6e208460c5745ab1f13d476dcbe04e1da7e592 +sendONFT - estimated nativeFee: 158.319172348046094655 +sendONFT - send tx on source chain: 0x72779c7549053194e42bcc78f78cf65e876867f0516dc91f28986c854e652596 +Wait for cross-chain tx finalization by LayerZero ... +sendONFT - received tx on destination chain: 0x2700a9d35c139eb84ba07b75490e6627a30e00bde130e3cb7c1cbb81c0326138 +Done in 53.50s. +``` +### Send ONFT-wrapped tokens back from destinaion chain to origin chain + +```bash +yarn send-onft-back-from-bnb-testnet +``` + +Expected log output: +```bash +npx hardhat run scripts/send_onft_back.ts --network bnbTestnet +sendONFTBack - proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnSrcChain:10230, lzEndpointIdOnDestChain:10102, gasDropInWeiOnDestChain:0, providedGasLimit:200000, receivingAccountAddress:0x57A4bD139Fb673D364A6f12Df9177A3f686625F3, sender: 0x60917645A28258a75836aF63633850c5F3561C1b, nftTokenId:2, nftTokenAddress:0xFddbA8928a763679fb8C99d12541B7c6177e9c3c +sendONFTBack - approve tx: 0xe5bfff108528efdc67e72896845f0ad3e0186b4ed64835e7c5f3552eaab69d99 +sendONFTBack - estimated nativeFee: 0.000498452810033053 +sendONFTBack - send tx on source chain: 0xa43bb5547a5a35730fe183b4d554416a4ea34852e510d21f24d173db75db4e79 +Wait for cross-chain tx finalization by LayerZero ... +sendONFTBack - received tx on destination chain: 0xb05fa2de194153819b26d17893278c485abbaf355fa24f26fbc7a4c759994cde +Done in 212.16s. +``` \ No newline at end of file From 0a9a14dfd4a168fd699e1b8c412dc691ef33b2d9 Mon Sep 17 00:00:00 2001 From: Vivek Jain Date: Mon, 3 Jun 2024 18:03:05 +0530 Subject: [PATCH 2/8] Add article to sidebar --- docs/build/isc/v1.0.0-rc.6/sidebars.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/build/isc/v1.0.0-rc.6/sidebars.js b/docs/build/isc/v1.0.0-rc.6/sidebars.js index 79e46174358..ccb6e865dca 100644 --- a/docs/build/isc/v1.0.0-rc.6/sidebars.js +++ b/docs/build/isc/v1.0.0-rc.6/sidebars.js @@ -204,6 +204,11 @@ module.exports = { }, ], }, + { + type: 'doc', + label: 'Send NFTs Across Chains', + id: 'how-tos/send-NFTs-across-chains', + }, ], }, { From 2253b0a7c833af4b77362507445d344d81f145f7 Mon Sep 17 00:00:00 2001 From: Lucas Tortora <85233773+lucas-tortora@users.noreply.github.com> Date: Mon, 3 Jun 2024 15:21:40 -0300 Subject: [PATCH 3/8] ISC - EDITS - Feature/nft transfer across chains edits (#1593) * edit structure add punctuation fix typos * spellcheck * Update docs/build/isc/v1.0.0-rc.6/docs/how-tos/send-NFTs-across-chains.md --------- Co-authored-by: Dr-Electron --- .../docs/how-tos/send-NFTs-across-chains.md | 230 +++++++++++------- 1 file changed, 142 insertions(+), 88 deletions(-) diff --git a/docs/build/isc/v1.0.0-rc.6/docs/how-tos/send-NFTs-across-chains.md b/docs/build/isc/v1.0.0-rc.6/docs/how-tos/send-NFTs-across-chains.md index 0ae68a9d500..b9cd007233e 100644 --- a/docs/build/isc/v1.0.0-rc.6/docs/how-tos/send-NFTs-across-chains.md +++ b/docs/build/isc/v1.0.0-rc.6/docs/how-tos/send-NFTs-across-chains.md @@ -2,121 +2,155 @@ ## Introduction -[LayerZero ONFT V1FV](https://docs.layerzero.network/V1) enables cross-chain transfers of existing ERC721 tokens. For testing purposes, ShimmerEVM testnet is chosen as the source chain, while the BNB testnet is chosen as the destination chain. +[LayerZero ONFT V1FV](https://docs.layerzero.network/V1) enables cross-chain transfers of existing ERC721 tokens. For +testing purposes, the ShimmerEVM Testnet is chosen as the source chain, while the BNB Testnet is chosen as the destination +chain. :::info Community Libs -You can clone the Utilities for LayerZero ONFT V1 from [IOTA Community GitHub Repository](https://github.com/iota-community/layerzero-onft-v1-utils). + +You can clone the Utilities for LayerZero ONFT V1 +from [IOTA Community GitHub Repository](https://github.com/iota-community/layerzero-onft-v1-utils). + ::: -### Why Would a User Need to Send ERC721 Tokens Across Chains? +## Why Would a User Need to Send ERC721 Tokens Across Chains? -By facilitating the movement of ERC721 tokens across chains, users gain flexibility and can optimize their NFT usage according to their specific needs, preferences, and circumstances. +By facilitating the movement of ERC721 tokens across chains, users gain flexibility and can optimize their NFT usage +according to their specific needs, preferences, and circumstances. -**Use-case 1** +### Enable the Existing ERC721 Tokens for Cross-Chain Sending -To enable the existing erc721 tokens for cross-chain sending, both ProxyONFT contract (on source chain) and ONFT contract (on destination chain) are needed. +To enable the existing ERC721 tokens for cross-chain sending, you will need the `ProxyONFT` contract on the source +chain, +and the ONFT contract on the destination chain) are needed. -The origin NFT token will be locked in the ProxyONFT so that the ONFT-wrapped tokens will be minted on the destination chain. If the NFT token already exists on the destination chain (this happens when the ONFT-wrapped token on destination chain is sent back to the source chain), no new token minting will happen. Instead, the NFT tokens will be transferred from the ONFT contract to the user wallet address. Relevant code +The origin NFT token will be locked in the `ProxyONFT` contract so that the ONFT-wrapped tokens will be minted on the +destination chain. If the NFT token already exists on the destination chain (i.e., when the ONFT-wrapped token on +the destination chain is sent back to the source chain), no new token minting will happen. Instead, the NFT tokens will be +transferred from the ONFT contract to the user's wallet address. Relevant code -**Use-case 2** +### Enable Cross-Chain Sending for Unloached ERC721 NFTs -For new erc721 tokens to be launched, ONFT standard can be leveraged to enable cross-chain sending without the need of ProxyONFT. Similarly to the above: lock on source chain and mint or transfer on destination chain. +If you are launching a new ERC721 token, you can use the ONFT standard to enable cross-chain sending without the need of +`ProxyONFT`. As with existing tokens, the NFT will be locked on the source chain and minted or transferred on the destination chain. -**Contracts:** +:::info Contract Documentation - [ProxyONFT721](https://docs.layerzero.network/v1/developers/evm-guides/contract-standards/721#proxyonft721sol) - [ProxyONFT1155](https://docs.layerzero.network/v1/developers/evm-guides/contract-standards/1155#proxyonft1155sol) - [ONFT721](https://docs.layerzero.network/v1/developers/evm-guides/contract-standards/721#onft721sol) - [ONFT1155](https://docs.layerzero.network/v1/developers/evm-guides/contract-standards/1155#onft1155sol) +- ::: + ## Scripts -### Deploy ProxyONFT and ONFT contracts +### Deploy the ProxyONFT and ONFT Contracts -#### For erc721 +#### For ERC721 - MyProxyONFT721.sol: - - CTOR: - - [minGasToTransferAndStore](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/onft721/ONFT721Core.sol#L169): The minimum gas needed to transfer and store your NFT, typically 100k for ERC721. This value would vary depending on your contract complexity, it's recommended to test. If this value is set too low, the destination tx will fail and a manual retry is needed - - lzEndpoint: LayerZero Endpoint on the source chain - - proxyToken: deployed contract address of the NFT tokens on source chain + - CTOR: + - [`minGasToTransferAndStore`](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/onft721/ONFT721Core.sol#L169): + The minimum gas needed to transfer and store your NFT is typically 100k for ERC721. This value would vary + depending on your contract complexity; it's recommended to test. If this value is set too low, the destination + tx will fail, and a manual retry is needed. + - `lzEndpoint`: LayerZero Endpoint on the source chain. + - `proxyToken`: deployed contract address of the NFT tokens on the source chain. - MyONFT721.sol: - - CTOR: - - name: name of the ONFT-wrapped tokens on the destination chain - - symbol: symbol of the ONFT-wrapped tokens on the destination chain - - [minGasToTransferAndStore](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/onft721/ONFT721Core.sol#L169): same as above - - lzEndpoint: - lzEndpoint: LayerZero Endpoint on the destination chain + - CTOR: + - `name`: name of the ONFT-wrapped tokens on the destination chain + - `symbol`: symbol of the ONFT-wrapped tokens on the destination chain + - [`minGasToTransferAndStore`](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/onft721/ONFT721Core.sol#L169): + The minimum gas needed to transfer and store your NFT typically 100k for ERC721. This value would vary + depending on your contract complexity; it's recommended to test. If this value is set too low, the destination + tx will fail, and a manual retry is needed. + - `lzEndpoint`: - lzEndpoint: LayerZero Endpoint on the destination chain -### Set trusted remote +### Set the Trusted Remote -For existing erc721 tokens, both of the ProxyONFT and ONFT contract instances need to be paired with each other. +For **existing ERC721 tokens**, the `ProxyONFT` and `ONFT` contract instances must be paired. -For the upcoming erc721 tokens that wanna leverage ONFT standard, the ONFT contract instance on the source chain needs to be paired with another ONFT contract instance on the destination chain. +For the **upcoming ERC721 tokens** that want to leverage the `ONFT` standard, the `ONFT` contract instance on the source chain +needs to be paired with another `ONFT` contract instance on the destination chain. -This setting is done via the method [setTrustedRemote](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/LzApp.sol#L138) +You can set this using the [`setTrustedRemote`](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/LzApp.sol#L138) method. -### Set min destination gas +### Set the `minGasLimit` -Both of the ProxyONFT contract instance and the ONFT contract instance need to be set for min gas on destination. +Both the `ProxyONFT` and the `ONFT` contract instanceS need to be set for minimum gas on destination([`minGasLimit`](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/LzApp.sol#L85C37-L85C48)). -This setting is done via the method [setMinDstGas](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/LzApp.sol#L159) +You can set his using the [`setMinDstGas`](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/LzApp.sol#L159) method. -Reference of [minGasLimit](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/LzApp.sol#L85C37-L85C48) +:::notice -**Notice:** -It is required that `minDstGas` <= `providedGasLimit` which is to be set via `adapterParams` upon cross-chain sending on source chain. +It is required that `minDstGas` <= `providedGasLimit`, which is to be set via `adapterParams` upon cross-chain sending on +the source chain. -### Set batch size limit +::: -Both of the ProxyONFT contract instance and the ONFT contract instance need to be set for batch size limit on source chain to limit the number of tokens to be sent to other chain when using the method [sendBatchFrom](https://github.com/LayerZero-Labs/solidity-examples/blob/c04e7d211b1b610f84761df943e6a38b0a53d304/contracts/token/onft721/ONFT721Core.sol#L67). +### Set the Batch Size Limit -This setting is done via the method [setDstChainIdToBatchLimit](https://github.com/LayerZero-Labs/solidity-examples/blob/c04e7d211b1b610f84761df943e6a38b0a53d304/contracts/token/onft721/ONFT721Core.sol#L194) +Both the `ProxyONFT` and the `ONFT` contract instances need to set a limit for the batch size on the source +chain to limit the number of tokens to be sent to another chain when using the +[`sendBatchFrom`](https://github.com/LayerZero-Labs/solidity-examples/blob/c04e7d211b1b610f84761df943e6a38b0a53d304/contracts/token/onft721/ONFT721Core.sol#L67) +method. -Reference of [dstChainIdToBatchLimit](https://github.com/LayerZero-Labs/solidity-examples/blob/c04e7d211b1b610f84761df943e6a38b0a53d304/contracts/token/onft721/ONFT721Core.sol#L90) +You can set this using the [`setDstChainIdToBatchLimit`](https://github.com/LayerZero-Labs/solidity-examples/blob/c04e7d211b1b610f84761df943e6a38b0a53d304/contracts/token/onft721/ONFT721Core.sol#L194) method; the default value is 1. -**Notice:** -Default value is 1 +## How To Send Tokens From a Source Chain to a Destination Chain (and Vice-Versa) -### Procedure to send tokens from source chain to destinaion chain and vice versa +### Required Contracts -For the existing erc721 tokens that involve with both ProxyONFT contract (on source chain) and ONFT contract (on destination chain), the token sending procedure is as follows: +#### From the Source Chain to the Destination Chain -1. The sender approves his erc721 tokens for the ProxyONFT contract -2. The sender calls the func `estimateSendFee()` of the ProxyONFT contract to estimate cross-chain fee to be paid in native on the source chain -3. The sender calls the func `sendFrom()` of the ProxyONFT contract to transfer tokens on source chain to destination chain -4. Optional: wait for the tx finalization on destination chain by using the lib [@layerzerolabs/scan-client](https://www.npmjs.com/package/@layerzerolabs/scan-client#example-usage) +For the existing ERC721 tokens, you will need the `ProxyONFT` contract on the source chain and the `ONFT` contract on +the destination chain. The procedure is as follows: -To send back the ONFT-wrapped tokens on destination chain to source chain, the procedure is similar (approve step is also needed) but the operations will be on the ONFT contract. +1. The sender approves his ERC721 tokens for the `ProxyONFT` contract. +2. The sender calls the function [`estimateSendFee()`](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/onft721/interfaces/IONFT721Core.sol#L70) of the ProxyONFT contract to estimate cross-chain fee to be paid in + native on the source chain. +3. The sender calls the function [`sendFrom()`](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/onft721/interfaces/IONFT721Core.sol#L36) of the ProxyONFT contract to transfer tokens on source chain to destination + chain. +4. (Optional) Wait for the transaction finalization on the destination chain by using the + [@layerzerolabs/scan-client](https://www.npmjs.com/package/@layerzerolabs/scan-client#example-usage) library. -**AdapterParams Notice** +#### From the Destination Chain Back to the Source Chain -- To set gas drop on destination in `adapterParams`, reference [this](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/libs/LzLib.sol#L44) +To send back the ONFT-wrapped tokens on the destination chain to the source chain, the procedure is similar as the +approve step is also required, but the operations will happen on the `ONFT` contract. - - The provided gas drop must <= the config one. Otherwise, will get error [dstNativeAmt too large](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/mocks/LZEndpointMock.sol#L413) +#### References and Tools -- To set default `adapterParams` without gas drop need, reference [this](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/libs/LzLib.sol#L34) +##### `AdapterParams` -**Appendix:** +- You can use the [LayerZero Repository](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/libs/LzLib.sol#L44) as a reference to set gas drop on the destination in `adapterParams`. + - The provided gas drop must be `<=` the config one. Otherwise, you will get [`dstNativeAmt` too large](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/mocks/LZEndpointMock.sol#L413) error. +- You can use the [LayerZero Repository](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/libs/LzLib.sol#L34) as a refernce to set default `adapterParams` without needing a gas drop. -- [function estimateSendFee()](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/onft721/interfaces/IONFT721Core.sol#L70) -- [function sendFrom()](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/onft721/interfaces/IONFT721Core.sol#L36) -- [@layerzerolabs/scan-client](https://www.npmjs.com/package/@layerzerolabs/scan-client#example-usage) -- [LayerZero Endpoint V1](https://docs.layerzero.network/v1/developers/technical-reference/mainnet/mainnet-addresses) -- [LayerZero explorer](https://testnet.layerzeroscan.com/) +##### LayerZero +- [LayerZero Endpoint V1](https://docs.layerzero.network/v1/developers/technical-reference/mainnet/mainnet-addresses) +- [LayerZero explorer](https://Testnet.layerzeroscan.com/) ### Install the Library -After you have cloned the [IOTA Community Utilities for LayerZero ONFT V! repository](https://github.com/iota-community/layerzero-onft-v1-utils), you should run the following command to install: +After you have cloned +the [IOTA Community Utilities for LayerZero ONFT V2 repository](https://github.com/iota-community/layerzero-onft-v1-utils), +you should run the following command to install: -``` +```bash yarn ``` -## Compile the Contracts +### Compile the Contracts -If you want to use the standard implementation for ERC20, copy the [`contracts-standard`](https://github.com/iota-community/layerzero-oft-V1-utils/tree/main/contracts-standard) folder to `contracts`. If you want to use a custom implementation, copy the [`contracts-wiota`](https://github.com/iota-community/layerzero-oft-V1-utils/tree/main/contracts-wiota) to `contracts`. Then, run the following command to compile the contracts: +If you want to use the standard implementation for ERC20, copy +the [`contracts-standard`](https://github.com/iota-community/layerzero-oft-V1-utils/tree/main/contracts-standard) folder +to `contracts`. If you want to use a custom implementation, copy +the [`contracts-wiota`](https://github.com/iota-community/layerzero-oft-V1-utils/tree/main/contracts-wiota) +to `contracts`. Then, run the following command to compile the contracts: ```bash yarn compile @@ -124,7 +158,9 @@ yarn compile ### Set Your Configuration -You should copy the template [`.env.example`](https://github.com/iota-community/layerzero-oft-V1-utils/blob/main/.env.example) file to a file called `.env`, and edit any of the configuration options you see fit. +You should copy the +template [`.env.example`](https://github.com/iota-community/layerzero-oft-V1-utils/blob/main/.env.example) file to a +file called `.env`, and edit any of the configuration options you see fit. ```bash cp .env.example .env @@ -132,26 +168,26 @@ cp .env.example .env ### Deploy the Contracts -## Deploy mock ERC721 +#### Deploy a mock ERC721 ```bash -yarn deploy-erc721-mock-smr-testnet +yarn deploy-ERC721-mock-smr-Testnet ``` Expected log output : ```bash -npx hardhat run scripts/deploy_erc721.ts --network shimmerEvmTestnet +npx hardhat run scripts/deploy_ERC721.ts --network shimmerEvmTestnet Deployed ERC721Mock contract address:0xFddbA8928a763679fb8C99d12541B7c6177e9c3c Done in 4.49s. ``` -### Deploy ProxyONFT721 on source chain +#### Deploy `ProxyONFT721` on the source chain -You can use the following command to deploy ProxyONFT721 on source chain (e.g. ShimmerEVM testnet): +You can use the following command to deploy ProxyONFT721 on the source chain (e.g., ShimmerEVM Testnet): ```bash -yarn deploy-proxy-onft-smr-testnet +yarn deploy-proxy-onft-smr-Testnet ``` Expected log output : @@ -162,12 +198,12 @@ Deployed MyProxyONFT721 contract address:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab Done in 4.50s. ``` -### Deploy ProxyONFT721 on destination chain +#### Deploy `ProxyONFT721` on the destination chain -You can use the following command to deploy ProxyONFT721 on destination chain (e.g. BNB testnet): +You can use the following command to deploy ProxyONFT721 on the destination chain (e.g., BNB Testnet): ```bash -yarn set-min-dest-gas-onft-bnb-testnet +yarn set-min-dest-gas-onft-bnb-Testnet ``` Expected log output : @@ -180,13 +216,16 @@ setMinDstGas (packetType 1) tx: 0x3a26ae40ac058099bfd8b85910009a5e5e8b03f16a5f03 Done in 9.34s. ``` -### Set min destination gas +### Set the Minimum Destination Gas + +#### On the source chain -You can use the following command to set min destination gas on ProxyONFT (source chain, e.g. ShimmerEVM testnet): +You can use the following command to set the minimum destination gas on the `ProxyONFT` contract on the source chain (e.g., ShimmerEVM Testnet): ```bash -yarn set-min-dest-gas-proxy-onft-smr-testnet +yarn set-min-dest-gas-proxy-onft-smr-Testnet ``` + Expected log output : ```bash @@ -197,10 +236,12 @@ setMinDstGas (packetType 1) tx: 0xe78fd3f0bf668fafbc423decd2cf14a27d74543af3ac9d Done in 6.07s. ``` -You can use the following command to set min destination gas on ONFT (destination chain, e.g. BNB testnet): +#### On the destination chain + +You can use the following command to set the minimum destination gas on the `ONFT` contract on the destination chain (e.g., BNB Testnet): ```bash -yarn set-min-dest-gas-onft-bnb-testnet +yarn set-min-dest-gas-onft-bnb-Testnet ``` Expected log output : @@ -213,13 +254,16 @@ setMinDstGas (packetType 1) tx: 0x3a26ae40ac058099bfd8b85910009a5e5e8b03f16a5f03 Done in 9.34s. ``` -### Set batch size limit +### Set the batch size limit -You can use the following command to set batch size limits on ProxyONFT (source chain, e.g. ShimmerEVM testnet): +#### On the source chain + +You can use the following command to set batch size limits on the `ProxyONFT` contract on the source chain (e.g., ShimmerEVM Testnet): ```bash -yarn set-batch-size-limit-proxy-onft-smr-testnet +yarn set-batch-size-limit-proxy-onft-smr-Testnet ``` + Expected log output : ```bash @@ -229,10 +273,12 @@ setBatchSizeLimit tx: 0x70c23b3d3d5e94ef82e50944f7eba93fa1fe8db3a5487ac371015e7a Done in 4.28s. ``` -You can use the following command to set batch size limits on ONFT (destination chain, e.g. BNB testnet): +#### On the destination chain + +You can use the following command to set batch size limits on the `ONFT` contract on the destination chain (e.g., BNB Testnet): ```bash -yarn set-batch-size-limit-onft-bnb-testnet +yarn set-batch-size-limit-onft-bnb-Testnet ``` Expected log output : @@ -244,13 +290,16 @@ setBatchSizeLimit tx: 0x8cb44c2195ac93da552c646677e6585c95ab172df19463637541933e Done in 4.26s. ``` -### Set trusted remote +### Set the Trusted Remote -You can use the following command to set trusted remote on ProxyONFT (source chain, e.g. ShimmerEVM testnet): +#### On the source chain + +You can use the following command to set a trusted remote on the `ProxyONFT` contract on the source chain (e.g., ShimmerEVM Testnet): ```bash -yarn set-remote-proxy-onft-smr-testnet +yarn set-remote-proxy-onft-smr-Testnet ``` + Expected log output : ```bash @@ -260,10 +309,12 @@ setTrustedRemote tx: 0xce52c0f25090ef7c1668ef04ff2f6098551c9f56b3ce881d17181bf10 Done in 4.24s. ``` -You can use the following command to set trusted remote on ONFT (destination chain, e.g. BNB testnet): +##### On the destination chain + +You can use the following command to set a trusted remote on the `ONFT` contract on the destination chain (e.g., BNB Testnet): ```bash -yarn set-remote-onft-bnb-testnet +yarn set-remote-onft-bnb-Testnet ``` Expected log output : @@ -275,13 +326,14 @@ setTrustedRemote tx: 0x311a0568b5afce7d601df2613f8ff80428d8a4d2f2c91012e0e4a8cbc Done in 4.88s. ``` -### Send origin tokens from source chain to destinaion chain +### Send Origin Tokens From the Source Chain To the Destination Chain ```bash -yarn send-onft-from-smr-testnet +yarn send-onft-from-smr-Testnet ``` Expected log output: + ```bash npx hardhat run scripts/send_onft.ts --network shimmerEvmTestnet sendONFT - proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnSrcChain:10230, lzEndpointIdOnDestChain:10102, gasDropInWeiOnDestChain:0, providedGasLimit:200000, receivingAccountAddress:0x5e812d3128D8fD7CEac08CEca1Cd879E76a6E028, sender: 0x57A4bD139Fb673D364A6f12Df9177A3f686625F3, nftTokenId:2, nftTokenAddress:0xFddbA8928a763679fb8C99d12541B7c6177e9c3c @@ -292,13 +344,15 @@ Wait for cross-chain tx finalization by LayerZero ... sendONFT - received tx on destination chain: 0x2700a9d35c139eb84ba07b75490e6627a30e00bde130e3cb7c1cbb81c0326138 Done in 53.50s. ``` -### Send ONFT-wrapped tokens back from destinaion chain to origin chain + +### Send ONFT-Wrapped Tokens Back From the Destination Chain Back To the Origin Chain ```bash -yarn send-onft-back-from-bnb-testnet +yarn send-onft-back-from-bnb-Testnet ``` Expected log output: + ```bash npx hardhat run scripts/send_onft_back.ts --network bnbTestnet sendONFTBack - proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnSrcChain:10230, lzEndpointIdOnDestChain:10102, gasDropInWeiOnDestChain:0, providedGasLimit:200000, receivingAccountAddress:0x57A4bD139Fb673D364A6f12Df9177A3f686625F3, sender: 0x60917645A28258a75836aF63633850c5F3561C1b, nftTokenId:2, nftTokenAddress:0xFddbA8928a763679fb8C99d12541B7c6177e9c3c @@ -308,4 +362,4 @@ sendONFTBack - send tx on source chain: 0xa43bb5547a5a35730fe183b4d554416a4ea348 Wait for cross-chain tx finalization by LayerZero ... sendONFTBack - received tx on destination chain: 0xb05fa2de194153819b26d17893278c485abbaf355fa24f26fbc7a4c759994cde Done in 212.16s. -``` \ No newline at end of file +``` From f839e5a2b36866dc621bec150d9e133914ce736f Mon Sep 17 00:00:00 2001 From: Dr-Electron Date: Mon, 3 Jun 2024 20:31:27 +0200 Subject: [PATCH 4/8] Update alpha docs --- .../docs/how-tos/send-NFTs-across-chains.md | 365 ++++++++++++++++++ docs/build/isc/v1.3-alpha/sidebars.js | 5 + 2 files changed, 370 insertions(+) create mode 100644 docs/build/isc/v1.3-alpha/docs/how-tos/send-NFTs-across-chains.md diff --git a/docs/build/isc/v1.3-alpha/docs/how-tos/send-NFTs-across-chains.md b/docs/build/isc/v1.3-alpha/docs/how-tos/send-NFTs-across-chains.md new file mode 100644 index 00000000000..b9cd007233e --- /dev/null +++ b/docs/build/isc/v1.3-alpha/docs/how-tos/send-NFTs-across-chains.md @@ -0,0 +1,365 @@ +# Send NFTs Across Chains + +## Introduction + +[LayerZero ONFT V1FV](https://docs.layerzero.network/V1) enables cross-chain transfers of existing ERC721 tokens. For +testing purposes, the ShimmerEVM Testnet is chosen as the source chain, while the BNB Testnet is chosen as the destination +chain. + +:::info Community Libs + +You can clone the Utilities for LayerZero ONFT V1 +from [IOTA Community GitHub Repository](https://github.com/iota-community/layerzero-onft-v1-utils). + +::: + +## Why Would a User Need to Send ERC721 Tokens Across Chains? + +By facilitating the movement of ERC721 tokens across chains, users gain flexibility and can optimize their NFT usage +according to their specific needs, preferences, and circumstances. + +### Enable the Existing ERC721 Tokens for Cross-Chain Sending + +To enable the existing ERC721 tokens for cross-chain sending, you will need the `ProxyONFT` contract on the source +chain, +and the ONFT contract on the destination chain) are needed. + +The origin NFT token will be locked in the `ProxyONFT` contract so that the ONFT-wrapped tokens will be minted on the +destination chain. If the NFT token already exists on the destination chain (i.e., when the ONFT-wrapped token on +the destination chain is sent back to the source chain), no new token minting will happen. Instead, the NFT tokens will be +transferred from the ONFT contract to the user's wallet address. Relevant code + +### Enable Cross-Chain Sending for Unloached ERC721 NFTs + +If you are launching a new ERC721 token, you can use the ONFT standard to enable cross-chain sending without the need of +`ProxyONFT`. As with existing tokens, the NFT will be locked on the source chain and minted or transferred on the destination chain. + +:::info Contract Documentation + +- [ProxyONFT721](https://docs.layerzero.network/v1/developers/evm-guides/contract-standards/721#proxyonft721sol) +- [ProxyONFT1155](https://docs.layerzero.network/v1/developers/evm-guides/contract-standards/1155#proxyonft1155sol) +- [ONFT721](https://docs.layerzero.network/v1/developers/evm-guides/contract-standards/721#onft721sol) +- [ONFT1155](https://docs.layerzero.network/v1/developers/evm-guides/contract-standards/1155#onft1155sol) + +- ::: + +## Scripts + +### Deploy the ProxyONFT and ONFT Contracts + +#### For ERC721 + +- MyProxyONFT721.sol: + - CTOR: + - [`minGasToTransferAndStore`](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/onft721/ONFT721Core.sol#L169): + The minimum gas needed to transfer and store your NFT is typically 100k for ERC721. This value would vary + depending on your contract complexity; it's recommended to test. If this value is set too low, the destination + tx will fail, and a manual retry is needed. + - `lzEndpoint`: LayerZero Endpoint on the source chain. + - `proxyToken`: deployed contract address of the NFT tokens on the source chain. + +- MyONFT721.sol: + - CTOR: + - `name`: name of the ONFT-wrapped tokens on the destination chain + - `symbol`: symbol of the ONFT-wrapped tokens on the destination chain + - [`minGasToTransferAndStore`](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/onft721/ONFT721Core.sol#L169): + The minimum gas needed to transfer and store your NFT typically 100k for ERC721. This value would vary + depending on your contract complexity; it's recommended to test. If this value is set too low, the destination + tx will fail, and a manual retry is needed. + - `lzEndpoint`: - lzEndpoint: LayerZero Endpoint on the destination chain + +### Set the Trusted Remote + +For **existing ERC721 tokens**, the `ProxyONFT` and `ONFT` contract instances must be paired. + +For the **upcoming ERC721 tokens** that want to leverage the `ONFT` standard, the `ONFT` contract instance on the source chain +needs to be paired with another `ONFT` contract instance on the destination chain. + +You can set this using the [`setTrustedRemote`](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/LzApp.sol#L138) method. + +### Set the `minGasLimit` + +Both the `ProxyONFT` and the `ONFT` contract instanceS need to be set for minimum gas on destination([`minGasLimit`](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/LzApp.sol#L85C37-L85C48)). + +You can set his using the [`setMinDstGas`](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/LzApp.sol#L159) method. + +:::notice + +It is required that `minDstGas` <= `providedGasLimit`, which is to be set via `adapterParams` upon cross-chain sending on +the source chain. + +::: + +### Set the Batch Size Limit + +Both the `ProxyONFT` and the `ONFT` contract instances need to set a limit for the batch size on the source +chain to limit the number of tokens to be sent to another chain when using the +[`sendBatchFrom`](https://github.com/LayerZero-Labs/solidity-examples/blob/c04e7d211b1b610f84761df943e6a38b0a53d304/contracts/token/onft721/ONFT721Core.sol#L67) +method. + +You can set this using the [`setDstChainIdToBatchLimit`](https://github.com/LayerZero-Labs/solidity-examples/blob/c04e7d211b1b610f84761df943e6a38b0a53d304/contracts/token/onft721/ONFT721Core.sol#L194) method; the default value is 1. + +## How To Send Tokens From a Source Chain to a Destination Chain (and Vice-Versa) + +### Required Contracts + +#### From the Source Chain to the Destination Chain + +For the existing ERC721 tokens, you will need the `ProxyONFT` contract on the source chain and the `ONFT` contract on +the destination chain. The procedure is as follows: + +1. The sender approves his ERC721 tokens for the `ProxyONFT` contract. +2. The sender calls the function [`estimateSendFee()`](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/onft721/interfaces/IONFT721Core.sol#L70) of the ProxyONFT contract to estimate cross-chain fee to be paid in + native on the source chain. +3. The sender calls the function [`sendFrom()`](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/onft721/interfaces/IONFT721Core.sol#L36) of the ProxyONFT contract to transfer tokens on source chain to destination + chain. +4. (Optional) Wait for the transaction finalization on the destination chain by using the + [@layerzerolabs/scan-client](https://www.npmjs.com/package/@layerzerolabs/scan-client#example-usage) library. + +#### From the Destination Chain Back to the Source Chain + +To send back the ONFT-wrapped tokens on the destination chain to the source chain, the procedure is similar as the +approve step is also required, but the operations will happen on the `ONFT` contract. + +#### References and Tools + +##### `AdapterParams` + +- You can use the [LayerZero Repository](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/libs/LzLib.sol#L44) as a reference to set gas drop on the destination in `adapterParams`. + - The provided gas drop must be `<=` the config one. Otherwise, you will get [`dstNativeAmt` too large](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/mocks/LZEndpointMock.sol#L413) error. +- You can use the [LayerZero Repository](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/libs/LzLib.sol#L34) as a refernce to set default `adapterParams` without needing a gas drop. + +##### LayerZero + +- [LayerZero Endpoint V1](https://docs.layerzero.network/v1/developers/technical-reference/mainnet/mainnet-addresses) +- [LayerZero explorer](https://Testnet.layerzeroscan.com/) + +### Install the Library + +After you have cloned +the [IOTA Community Utilities for LayerZero ONFT V2 repository](https://github.com/iota-community/layerzero-onft-v1-utils), +you should run the following command to install: + +```bash +yarn +``` + +### Compile the Contracts + +If you want to use the standard implementation for ERC20, copy +the [`contracts-standard`](https://github.com/iota-community/layerzero-oft-V1-utils/tree/main/contracts-standard) folder +to `contracts`. If you want to use a custom implementation, copy +the [`contracts-wiota`](https://github.com/iota-community/layerzero-oft-V1-utils/tree/main/contracts-wiota) +to `contracts`. Then, run the following command to compile the contracts: + +```bash +yarn compile +``` + +### Set Your Configuration + +You should copy the +template [`.env.example`](https://github.com/iota-community/layerzero-oft-V1-utils/blob/main/.env.example) file to a +file called `.env`, and edit any of the configuration options you see fit. + +```bash +cp .env.example .env +``` + +### Deploy the Contracts + +#### Deploy a mock ERC721 + +```bash +yarn deploy-ERC721-mock-smr-Testnet +``` + +Expected log output : + +```bash +npx hardhat run scripts/deploy_ERC721.ts --network shimmerEvmTestnet +Deployed ERC721Mock contract address:0xFddbA8928a763679fb8C99d12541B7c6177e9c3c +Done in 4.49s. +``` + +#### Deploy `ProxyONFT721` on the source chain + +You can use the following command to deploy ProxyONFT721 on the source chain (e.g., ShimmerEVM Testnet): + +```bash +yarn deploy-proxy-onft-smr-Testnet +``` + +Expected log output : + +```bash +npx hardhat run scripts/deploy_proxy_onft721.ts --network shimmerEvmTestnet +Deployed MyProxyONFT721 contract address:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2 +Done in 4.50s. +``` + +#### Deploy `ProxyONFT721` on the destination chain + +You can use the following command to deploy ProxyONFT721 on the destination chain (e.g., BNB Testnet): + +```bash +yarn set-min-dest-gas-onft-bnb-Testnet +``` + +Expected log output : + +```bash +export isForProxy=false && npx hardhat run scripts/set_min_destination_gas.ts --network bnbTestnet +setMinDstGas - isForProxy:false, proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnRemoteChain:10230, minDstGas:150000 +setMinDstGas (packetType 0) tx: 0xce044ded17daa77a8aefc3d39b99c5381216eb4057ddce6253affde6cda2091c +setMinDstGas (packetType 1) tx: 0x3a26ae40ac058099bfd8b85910009a5e5e8b03f16a5f032b572827d48be8f2b0 +Done in 9.34s. +``` + +### Set the Minimum Destination Gas + +#### On the source chain + +You can use the following command to set the minimum destination gas on the `ProxyONFT` contract on the source chain (e.g., ShimmerEVM Testnet): + +```bash +yarn set-min-dest-gas-proxy-onft-smr-Testnet +``` + +Expected log output : + +```bash +export isForProxy=true && npx hardhat run scripts/set_min_destination_gas.ts --network shimmerEvmTestnet +setMinDstGas - isForProxy:true, proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnRemoteChain:10102, minDstGas:150000 +setMinDstGas (packetType 0) tx: 0xcab06e9989448153a4bbc1bb166fc2d33467f3311d1851bf2ff719d982daa613 +setMinDstGas (packetType 1) tx: 0xe78fd3f0bf668fafbc423decd2cf14a27d74543af3ac9daf031f0b278c22ea78 +Done in 6.07s. +``` + +#### On the destination chain + +You can use the following command to set the minimum destination gas on the `ONFT` contract on the destination chain (e.g., BNB Testnet): + +```bash +yarn set-min-dest-gas-onft-bnb-Testnet +``` + +Expected log output : + +```bash +export isForProxy=false && npx hardhat run scripts/set_min_destination_gas.ts --network bnbTestnet +setMinDstGas - isForProxy:false, proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnRemoteChain:10230, minDstGas:150000 +setMinDstGas (packetType 0) tx: 0xce044ded17daa77a8aefc3d39b99c5381216eb4057ddce6253affde6cda2091c +setMinDstGas (packetType 1) tx: 0x3a26ae40ac058099bfd8b85910009a5e5e8b03f16a5f032b572827d48be8f2b0 +Done in 9.34s. +``` + +### Set the batch size limit + +#### On the source chain + +You can use the following command to set batch size limits on the `ProxyONFT` contract on the source chain (e.g., ShimmerEVM Testnet): + +```bash +yarn set-batch-size-limit-proxy-onft-smr-Testnet +``` + +Expected log output : + +```bash +export isForProxy=true && npx hardhat run scripts/set_batch_size_limit.ts --network shimmerEvmTestnet +setBatchSizeLimit - isForProxy:true, proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnRemoteChain:10102, batchSizeLimit:1 +setBatchSizeLimit tx: 0x70c23b3d3d5e94ef82e50944f7eba93fa1fe8db3a5487ac371015e7a14482e75 +Done in 4.28s. +``` + +#### On the destination chain + +You can use the following command to set batch size limits on the `ONFT` contract on the destination chain (e.g., BNB Testnet): + +```bash +yarn set-batch-size-limit-onft-bnb-Testnet +``` + +Expected log output : + +```bash +export isForProxy=false && npx hardhat run scripts/set_batch_size_limit.ts --network bnbTestnet +setBatchSizeLimit - isForProxy:false, proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnRemoteChain:10230, batchSizeLimit:1 +setBatchSizeLimit tx: 0x8cb44c2195ac93da552c646677e6585c95ab172df19463637541933ec70dc9b8 +Done in 4.26s. +``` + +### Set the Trusted Remote + +#### On the source chain + +You can use the following command to set a trusted remote on the `ProxyONFT` contract on the source chain (e.g., ShimmerEVM Testnet): + +```bash +yarn set-remote-proxy-onft-smr-Testnet +``` + +Expected log output : + +```bash +export isForProxy=true && npx hardhat run scripts/set_trusted_remote.ts --network shimmerEvmTestnet +setTrustedRemote - isForProxy:true, proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnRemoteChain:10102 +setTrustedRemote tx: 0xce52c0f25090ef7c1668ef04ff2f6098551c9f56b3ce881d17181bf106457016 +Done in 4.24s. +``` + +##### On the destination chain + +You can use the following command to set a trusted remote on the `ONFT` contract on the destination chain (e.g., BNB Testnet): + +```bash +yarn set-remote-onft-bnb-Testnet +``` + +Expected log output : + +```bash +export isForProxy=false && npx hardhat run scripts/set_trusted_remote.ts --network bnbTestnet +setTrustedRemote - isForProxy:false, proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnRemoteChain:10230 +setTrustedRemote tx: 0x311a0568b5afce7d601df2613f8ff80428d8a4d2f2c91012e0e4a8cbc0aedf59 +Done in 4.88s. +``` + +### Send Origin Tokens From the Source Chain To the Destination Chain + +```bash +yarn send-onft-from-smr-Testnet +``` + +Expected log output: + +```bash +npx hardhat run scripts/send_onft.ts --network shimmerEvmTestnet +sendONFT - proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnSrcChain:10230, lzEndpointIdOnDestChain:10102, gasDropInWeiOnDestChain:0, providedGasLimit:200000, receivingAccountAddress:0x5e812d3128D8fD7CEac08CEca1Cd879E76a6E028, sender: 0x57A4bD139Fb673D364A6f12Df9177A3f686625F3, nftTokenId:2, nftTokenAddress:0xFddbA8928a763679fb8C99d12541B7c6177e9c3c +sendONFT - approve tx: 0xa871bc79e45bf20f33c626044d6e208460c5745ab1f13d476dcbe04e1da7e592 +sendONFT - estimated nativeFee: 158.319172348046094655 +sendONFT - send tx on source chain: 0x72779c7549053194e42bcc78f78cf65e876867f0516dc91f28986c854e652596 +Wait for cross-chain tx finalization by LayerZero ... +sendONFT - received tx on destination chain: 0x2700a9d35c139eb84ba07b75490e6627a30e00bde130e3cb7c1cbb81c0326138 +Done in 53.50s. +``` + +### Send ONFT-Wrapped Tokens Back From the Destination Chain Back To the Origin Chain + +```bash +yarn send-onft-back-from-bnb-Testnet +``` + +Expected log output: + +```bash +npx hardhat run scripts/send_onft_back.ts --network bnbTestnet +sendONFTBack - proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnSrcChain:10230, lzEndpointIdOnDestChain:10102, gasDropInWeiOnDestChain:0, providedGasLimit:200000, receivingAccountAddress:0x57A4bD139Fb673D364A6f12Df9177A3f686625F3, sender: 0x60917645A28258a75836aF63633850c5F3561C1b, nftTokenId:2, nftTokenAddress:0xFddbA8928a763679fb8C99d12541B7c6177e9c3c +sendONFTBack - approve tx: 0xe5bfff108528efdc67e72896845f0ad3e0186b4ed64835e7c5f3552eaab69d99 +sendONFTBack - estimated nativeFee: 0.000498452810033053 +sendONFTBack - send tx on source chain: 0xa43bb5547a5a35730fe183b4d554416a4ea34852e510d21f24d173db75db4e79 +Wait for cross-chain tx finalization by LayerZero ... +sendONFTBack - received tx on destination chain: 0xb05fa2de194153819b26d17893278c485abbaf355fa24f26fbc7a4c759994cde +Done in 212.16s. +``` diff --git a/docs/build/isc/v1.3-alpha/sidebars.js b/docs/build/isc/v1.3-alpha/sidebars.js index a01017561cc..3ac0d6ff92a 100644 --- a/docs/build/isc/v1.3-alpha/sidebars.js +++ b/docs/build/isc/v1.3-alpha/sidebars.js @@ -209,6 +209,11 @@ module.exports = { }, ], }, + { + type: 'doc', + label: 'Send NFTs Across Chains', + id: 'how-tos/send-NFTs-across-chains', + }, ], }, { From e85f7c4f0c0142f832e7d557a75cd92e77f21ccb Mon Sep 17 00:00:00 2001 From: Dr-Electron Date: Mon, 3 Jun 2024 20:55:48 +0200 Subject: [PATCH 5/8] Update sidebars --- docs/build/isc/v1.1/sidebars.js | 10 +++++----- docs/build/isc/v1.3-alpha/sidebars.js | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/build/isc/v1.1/sidebars.js b/docs/build/isc/v1.1/sidebars.js index 3ac0d6ff92a..788f20e49e1 100644 --- a/docs/build/isc/v1.1/sidebars.js +++ b/docs/build/isc/v1.1/sidebars.js @@ -89,6 +89,11 @@ module.exports = { label: 'Create NFTs - ERC721', id: 'how-tos/ERC721', }, + { + type: 'doc', + label: 'Send NFTs Across Chains', + id: 'how-tos/send-NFTs-across-chains', + }, { type: 'doc', label: 'Test Smart Contracts', @@ -209,11 +214,6 @@ module.exports = { }, ], }, - { - type: 'doc', - label: 'Send NFTs Across Chains', - id: 'how-tos/send-NFTs-across-chains', - }, ], }, { diff --git a/docs/build/isc/v1.3-alpha/sidebars.js b/docs/build/isc/v1.3-alpha/sidebars.js index 3ac0d6ff92a..788f20e49e1 100644 --- a/docs/build/isc/v1.3-alpha/sidebars.js +++ b/docs/build/isc/v1.3-alpha/sidebars.js @@ -89,6 +89,11 @@ module.exports = { label: 'Create NFTs - ERC721', id: 'how-tos/ERC721', }, + { + type: 'doc', + label: 'Send NFTs Across Chains', + id: 'how-tos/send-NFTs-across-chains', + }, { type: 'doc', label: 'Test Smart Contracts', @@ -209,11 +214,6 @@ module.exports = { }, ], }, - { - type: 'doc', - label: 'Send NFTs Across Chains', - id: 'how-tos/send-NFTs-across-chains', - }, ], }, { From 6a6661aec8bb7a39e7984778d89684e522cb87d0 Mon Sep 17 00:00:00 2001 From: Dr-Electron Date: Mon, 3 Jun 2024 21:01:33 +0200 Subject: [PATCH 6/8] Update docs/build/isc/v1.1/docs/how-tos/send-NFTs-across-chains.md --- docs/build/isc/v1.1/docs/how-tos/send-NFTs-across-chains.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/build/isc/v1.1/docs/how-tos/send-NFTs-across-chains.md b/docs/build/isc/v1.1/docs/how-tos/send-NFTs-across-chains.md index b9cd007233e..391a6623d60 100644 --- a/docs/build/isc/v1.1/docs/how-tos/send-NFTs-across-chains.md +++ b/docs/build/isc/v1.1/docs/how-tos/send-NFTs-across-chains.md @@ -41,7 +41,7 @@ If you are launching a new ERC721 token, you can use the ONFT standard to enable - [ONFT721](https://docs.layerzero.network/v1/developers/evm-guides/contract-standards/721#onft721sol) - [ONFT1155](https://docs.layerzero.network/v1/developers/evm-guides/contract-standards/1155#onft1155sol) -- ::: +::: ## Scripts From 7076ef4a165e7e2a46409dbb85d25d5e11db7ca5 Mon Sep 17 00:00:00 2001 From: Dr-Electron Date: Mon, 3 Jun 2024 21:03:05 +0200 Subject: [PATCH 7/8] Update docs/build/isc/v1.1/docs/how-tos/send-NFTs-across-chains.md --- docs/build/isc/v1.1/docs/how-tos/send-NFTs-across-chains.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/build/isc/v1.1/docs/how-tos/send-NFTs-across-chains.md b/docs/build/isc/v1.1/docs/how-tos/send-NFTs-across-chains.md index 391a6623d60..273c11009b4 100644 --- a/docs/build/isc/v1.1/docs/how-tos/send-NFTs-across-chains.md +++ b/docs/build/isc/v1.1/docs/how-tos/send-NFTs-across-chains.md @@ -83,7 +83,7 @@ Both the `ProxyONFT` and the `ONFT` contract instanceS need to be set for minimu You can set his using the [`setMinDstGas`](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/LzApp.sol#L159) method. -:::notice +:::info It is required that `minDstGas` <= `providedGasLimit`, which is to be set via `adapterParams` upon cross-chain sending on the source chain. From 6d9577b432fd7ebc8790e916c245c60f395efffc Mon Sep 17 00:00:00 2001 From: Dr-Electron Date: Mon, 3 Jun 2024 21:09:08 +0200 Subject: [PATCH 8/8] Copy fixes --- .../isc/v1.3-alpha/docs/how-tos/send-NFTs-across-chains.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/build/isc/v1.3-alpha/docs/how-tos/send-NFTs-across-chains.md b/docs/build/isc/v1.3-alpha/docs/how-tos/send-NFTs-across-chains.md index b9cd007233e..273c11009b4 100644 --- a/docs/build/isc/v1.3-alpha/docs/how-tos/send-NFTs-across-chains.md +++ b/docs/build/isc/v1.3-alpha/docs/how-tos/send-NFTs-across-chains.md @@ -41,7 +41,7 @@ If you are launching a new ERC721 token, you can use the ONFT standard to enable - [ONFT721](https://docs.layerzero.network/v1/developers/evm-guides/contract-standards/721#onft721sol) - [ONFT1155](https://docs.layerzero.network/v1/developers/evm-guides/contract-standards/1155#onft1155sol) -- ::: +::: ## Scripts @@ -83,7 +83,7 @@ Both the `ProxyONFT` and the `ONFT` contract instanceS need to be set for minimu You can set his using the [`setMinDstGas`](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/LzApp.sol#L159) method. -:::notice +:::info It is required that `minDstGas` <= `providedGasLimit`, which is to be set via `adapterParams` upon cross-chain sending on the source chain.