NFT Global Entry
Crosschain token gating for the EVM ecosystem
NFT Global Entry allows developers to deploy smart contracts on EVM chains that depend on NFT ownership data from other EVM chains. Global Entry is an alternative to bridging that is only suitable for low or no value transactions. Global Entry tooling complements Gasless Transactions and Burner Wallets, but can also be used independently to token gate transactions across any of our supported EVM chains.
NFT Global Entry uses EIP-3668 Offchain Lookup errors to instruct clients how to fetch a proof that can be used in a transaction. This trusted ownership proof is generated by 0xEssential's Ownership Oracle and validated by an EssentialForwarder
contract. Our SDKs handle proof fetching for both Gasless and native transactions.
Why Use Global Entry
Global Entry's live lookup for crosschain NFT authorization is much more convenient for users and developers alike. While not suited for every application, the trust minimized approach is arguably a more secure solution where assets remain on their original chain, safely controlled by hardware wallets.
Instead of forcing users to bridge NFTs before getting to experience your app, Global Entry allows a much more seamless user experience. Developers save time not having to integrate bridging, and our client SDKs make it easy to adopt Global Entry transactions in your app.
Global Entry works great with Gasless Transactions and Burner Wallets, but you can use Global Entry with L2 native transactions and add other integrations later.
Architecture
To implement 0xEssential's NFT Global Entry, consider these 4 entities:
Implementation Contract
The implementation or target contract is your smart contract that contains your business logic. You will not be able to use Global Entry with existing contracts. Your implementation contract must inherit EssentialContext
and replace all msg.sender
calls with _msgSender()
. You'll also use _msgNFT()
to access data about the NFT being used. You can deploy this contract on any EVM chain we support.
Forwarder
A forwarding contract is typically used for meta-transactions. EssentialForwarder
supports meta-transactions, but we also use it as a middleware contract for NFT Global entry, even for native transactions, where the client "preflights" a transaction against a public read function. EssentialForwarder
instructs clients how to fetch an ownership proof and how to submit it in a transaction. 0xEssential provides canonical forwarder deployments on most EVM chains at 0x000000000066b3aED7Ae8263588dA67fF381FfCa
. You may also deploy your own EssentialForwarder
to customize the name.
NFT Ownership Oracle
0xEssential provides an Oracle API that generates ownership proofs for Global Entry transactions. The code for this API is open source and you're free to run your own instance. In a typical integration, you don't need to integrate this API manually - our client SDKs for Gasless and native transactions handle proof fetching and transaction submission. The Ownership Oracle respects Delegate Cash delegations from the NFT chain to generate proofs for any authorized requester.
Signer
The user submitting a Global Entry transactions and their connected address is the Signer. 0xEssential's React SDK handles all of the preflighting, proof fetching and transaction submission. The usePrepareContractWrite
hook mimics wagmi
and accepts overrides to specify the NFT being used in the transaction. A transaction signer can also specify a vault address that owns the NFT being used - if the signer has authority to use the NFT via Delegate Cash, Global Entry will consider the transaction valid.
Getting Started
To use Global Entry, your smart contract must inherit EssentialContext
, so you won't be able to use Global Entry with contracts that are already deployed. This inheritable contract is available in our Solidity SDK available on NPM or via Github for installation in a foundry project.
0xEssential's client SDK is based on wagmi
and ethers
. Adding Global Entry transactions to your frontend is as simple as installing our package and replacing usePrepareContractWrite
and useContractWrite
hook imports with the versions from our SDK.
Last updated