One NFT on infinite networks: a read only NFT mirror that replicates NFT cross-chain using EIP3668 CCIP
Today NFT only exists on a single network where it is minted at or bridged to. There has been some experiment on Omnichain NFT where a NFT collection can span multiple networks. However, you cannot have an instance of NFT on multiple networks. For example, you can bridge your ENS NFT to Optimism but you would no longer be able to attest its ownership on the mainnet. Another example is that POAP mints on Gnosis chain and it would be really cool if I can showcase it on application that supports other networks only (e.g. Instagram only supports mainnet and polygon for now)
The high level idea is to deploy NFT contracts on respective networks that simply mirror the state of the NFT contract on the NFT's root network. The mirrored contracts are read only and can only be used to verify ownership and retrieve metadata. We use EIP3668 to do just that.
We considered a few naive implementations:
It turns out that ENS has already thought about this and been working on a series of EIPs that make this possible. https://docs.ens.domains/dapp-developer-guide/ens-l2-offchain
We tap into EIP3668 which allows us to access off chain data in a backwards compatible and standardized way. Indeed, "Viewing token information for tokens stored on an L2 solution as if they were native L1 tokens." was one of the originally conceived use case. https://eips.ethereum.org/EIPS/eip-3668
To do so, we implemented a ERC721Mirror.sol contract that delegates the critical view functions to off chain callback: https://github.com/saurfang/poap-mirror/blob/scaffold-nextjs/packages/hardhat/contracts/ERC721Mirror.sol We then implemented the backend server that unpack and pack EIP3668 requests and responses https://replit.com/@ericzhang98/FabulousSnowApplicationstack
Unfortunately, we discovered the hard way that EIP3668 is not well supported on the client side. Ethers.js only added support in 3.6.0 and many projects in the wild is still on 3.4.x. Neither Etherscan or Opensea respected the OffchainLookup revert code. Instead, we were able to validate the implementation using tests: https://github.com/saurfang/poap-mirror/blob/scaffold-nextjs/packages/hardhat/test/myTest.js