On this page
OmniseaONFTs (Coming soon)
NFT routes are coming soon. The current production deployment supports OFT transfers for ERC-20 assets only.
This page documents the planned ERC-721 bridge surface so integrators can see the intended shape ahead of launch. Do not use old ONFT beta addresses for live transfers. Verified ONFT deployment addresses will be published in Deployments once NFT routes are active.
contract OmniseaONFTs is OmniseaUpgradeableCoreThe planned contract will mirror the live Omnisea route model where appropriate - fees, options validation, peer setup and first-set activation timing, hooks, owner functions, and failed-message recovery. This page documents expected NFT-specific differences and should not be treated as live deployment documentation.
Send functions
The value argument is a tokenId, not an amount. Each function uses the full hook-aware signature; use an empty hook for a plain transfer.
sendOriginal
Locks an original NFT (requires approve or setApprovalForAll to the bridge) and sends it to dstEid:
function sendOriginal(
uint32 dstEid,
address originalCollection,
uint256 tokenId,
address recipient,
bool isFirstTransfer,
Hook calldata hook,
bytes calldata options
) external payable returns (MessagingReceipt memory receipt);sendONFT
Burns a representation NFT and sends it back home or onward. Reverts with RepresentationMustUseSendONFT if you call sendOriginal with a representation, and NotRepresentation if you call sendONFT with anything else:
function sendONFT(
uint32 dstEid,
address representation,
uint256 tokenId,
address recipient,
bool isFirstTransfer,
Hook calldata hook,
bytes calldata options
) external payable returns (MessagingReceipt memory receipt);quoteSendOriginal / quoteSendONFT
View counterparts returning the exact total fee, like the OFT quotes.
What the message carries
The NFT payload propagates collection metadata, the token's URI, and ERC-2981 royalty configuration with every transfer:
struct TokenPayload {
MessageKind messageKind; // Transfer | Restore
uint32 originalChainId;
address originalToken;
uint256 tokenId;
address sender;
address recipient;
string tokenName;
string tokenSymbol;
string tokenURI; // per-token, stored on the representation at mint
string contractURI;
address royaltyReceiver; // ERC-2981 default royalty, propagated from the original
uint96 royaltyBps;
address contractOwner; // original collection's owner() - becomes the representation's owner
Hook hook;
}See Representations for what the issuer-owned representation can do with this metadata.
Identity & discovery
function collectionKey(uint32 originalChainId, address originalToken) public pure returns (bytes32);
function representationFor(uint32 originalChainId, address originalToken) external view returns (address);
function predictRepresentation(uint32 originalChainId, address originalToken) external view returns (address);
/// Reverse lookup for local representations.
mapping(address representation => OriginalCollection original) public onftToOriginal;
/// Forward lookup by collection key.
mapping(bytes32 originalCollectionKey => address representation) public originalToONFT;
/// Per-token lock registry for originals held by the bridge.
mapping(address originalToken => mapping(uint256 tokenId => bool locked)) public locked;Safe-transfer guard
The bridge implements onERC721Received defensively: it only accepts the exact token it is actively locking inside a sendOriginal call. Any other NFT pushed at the bridge via safeTransferFrom reverts with UnexpectedERC721Received - tokens cannot be stranded in the bridge by accident.
NFT-specific events & errors
event OriginalLocked(address indexed originalToken, uint256 indexed tokenId, address indexed owner);
event OriginalUnlocked(address indexed originalToken, uint256 indexed tokenId, address indexed recipient);
event RepresentationBurned(address indexed representation, uint32 indexed originalChainId, address indexed originalToken, address owner, uint256 tokenId);
error NotLocked(); // unlock for a token the bridge does not hold
error TokenAlreadyLocked(); // double-lock attempt
error UnexpectedERC721Received(); // unsolicited safeTransferFrom into the bridge
error RepresentationMustUseSendONFT(); // sendOriginal called with a representationRepresentationDeployed, RepresentationMinted, BridgeMessageSent/Received, hook events, recovery events, and configuration events match the OFT bridge with tokenId taking the place of amount.
Metadata
Once NFT routes are live, first transfers will deploy an ONFT representation initialized with the original collection's name, symbol, contractURI, default royalty, and owner. Each minted token will store the tokenURI carried in its transfer, so bridged NFTs can render correctly in wallets and marketplaces - including ERC-2981 royalty queries.