This guide provides context on the steps required to list your game items, collectibles, or other ERC-721 assets on Immutable X. It's a good overview of tasks and concepts if you're new to the space, or if you want to learn more about the benefits of minting on Immutable X.
Ready to start?
If you're already across the details and ready to get started, check our onboarding guide.
Immutable X is a “Layer 2” (L2) scaling solution built on top of Ethereum, otherwise known as Layer 1 (L1). Immutable X inherits the network and security of the Ethereum blockchain, and allows customers to mint and trade NFTs at zero gas cost, carbon-neutrally, and at more than 9,000 transactions per second (TPS) — whereas Ethereum currently does 5.
For more detail on how it works, see:
Immutable X has a shared assetbook. Every asset minted into Immutable X is stored in the shared assetbook. This enables any application on Immutable X to view and display the assets of any other application, which helps deliver the best liquidity outcome for projects on Immutable X.
- Project A (marketplace A) mints an NFT (NFT-A) on Immutable X.
- Project B (marketplace B) displays NFT-A on its marketplace.
- Project B users see the NFT, incrementally increasing demand for NFT-A.
- Project A's primary and secondary sales increase.
When you’ve downloaded the samples, navigate to the Asset.sol file in the contracts folder. This will be used as the initial code for the contract.
Immutable X has a shared orderbook. Every order submitted to Immutable X is stored by Immutable and made available to all marketplaces.
Building on Immutable X means that you:
- Do not need to build, manage or maintain your own orderbook to facilitate trades.
- Have access to pools of demand that exist outside of a single marketplace.
Here’s an example:
- Project A (marketplace A) lists an NFT (NFT-A) in marketplace A.
- Project B (marketplace B) displays NFT-A on marketplace B.
- Project B users see the NFT and purchase NFT-A on marketplace B.
- NFT-A sale is complete.
In this example, marketplace A receives their market-maker fee and marketplace B receives their market-taker fee on the sale. To summarize, having orders listed on more than one marketplace means that your orders are more likely to sell faster, or for a greater price if on auction.
The platform supports two types of metadata:
- Immutable metadata — Set at the time of asset creation, enforced by the proof, and available on-chain when an L2-minted NFT is withdrawn for the first time. This is also called the blueprint or
mintingBlob. This is where you should store permanent properties, such as IDs or IPFS hashes.
- Mutable metadata — Fully controlled by the application, and not recorded on-chain, mutable metadata is most useful for marketplaces to describe assets accurately to users. Every application must register a metadata schema for their collection, which specifies the metadata types.
Projects are expected to self-host their media assets, including both the endpoints for the metadata of the assets, as well as other media defined by the metadata. When registering your collection's contract with Immutable X, you need to provide a metadata API endpoint for us to retrieve metadata properties for each of your NFTs.
Our metadata crawler will attempt to find the metadata for every newly minted NFT by querying
<project_metadata_endpoint>/<token_id>, so it's important that the endpoint you give us matches this format.
After an asset from your collection is minted, we store the metadata returned by this endpoint in our database, and subsequent callers can use these metadata properties in filter queries to the APIs.
- Your metadata endpoint should be able to handle a large amount of requests depending on the volume of your mints. If it fails to provide a response to the crawler after a few retries, or if it gets rate limited, your assets may be displayed without metadata.
- The endpoint URL must be a valid
httpsURL. If you are using IPFS, you should set up a dedicated (not public) gateway.
On-chain metadata refers to properties or characteristics that you set for your assets within the smart contract itself, meaning data that is stored on the blockchain (A.K.A on-chain).
The purpose of on-chain data is to uniquely identify the value of the NFT, for example, rarity or character type, but you should store as little data on-chain as possible. In cases where NFTs represent artworks or other media forms, uploading an entire JPEG to the blockchain will cost a huge amount. This is why it's common for most NFT metadata to be stored off-chain.
NFTs often use a Uniform Resource Identifier (URI) for off-chain metadata, which is a link to an external off-chain resource where the metadata for that particular asset is stored, usually in a JSON format. This URI is stored in the
tokenURI field as part of the ERC-721 standard:
function tokenURI(uint256 _tokenId) external view returns (string);
Because this data is off-chain, whoever controls the storage location has the ability to change it. For example, if their server is shut down the metadata will no longer be accessible. Concerns like this are often why developers choose to use IPFS hashes or links to guarantee the reliability and immutability of this off-chain data.
Currently, your collection’s metadata schema can only be updated by contacting support. We're currently working on a self-serve model, which will allow applications to update their collections' metadata on-demand.
The blueprint is a required field defined at the time of minting on Immutable X for each NFT. This represents the on-chain immutable metadata of the NFT that will be written to the blockchain when it is withdrawn from Immutable X.
The blueprint string can be of any format; typically it's a comma delimited string (e.g. "100,water,2,3") or an IPFS hash. This is passed to the
mintFor function in your smart contract, where you can implement custom logic to decode it on-chain or just save it as it is.
For a better understanding of how the blueprint is used, take a look at our smart contract templates in this repo: imx-contracts
- Blueprint data — The metadata that appears on Immutable X does not read any data from the blueprint, so there's no reason to define a blueprint as an entire JSON string. Instead, it could be a link, hash, or a few select properties to optionally decode and save in custom mappings in your smart contract.
- Token ID increments — In a Layer 1 smart contract, it's common for the ERC-721 token ID to be incremented in the minting function. With Immutable X, the token ID is defined at the time of minting to Immutable X and passed to the
mintForfunction in the minting blob, which then gets decoded into the respective ID and blueprint variables. You will have to keep track of the token ID on your end and increment it off-chain for every mint.
For a smart contract to work with Immutable X, we need an implementation of a
mintFor function, which is what our Stark contract calls at the time of withdrawing a minted token from L2 to L1. There is no smart contract interaction at the time of minting on L2, although the minted token will have a L1 representation, token ID, and immutable metadata.
When minting on Immutable X, you will give us the token ID, which is the L1 token ID representing the token in your smart contract. As mentioned above, you also have to provide a blueprint for each token. The blueprint represents the on-chain, immutable metadata of the NFT that will be passed (along with the token ID) to your
If you have an existing smart contract you want to mint assets into, you'll need to set up a proxy contract to implement the
mintFor action and ensure that this proxy contract has the appropriate permissions to mint on your non-mintable ERC-721 contract. Your main contract must adopt a flexible enough permission structure to allow for new 'minter' proxy contracts.
You can mint more than one asset in an API call, and even mint multiple assets to multiple users.
After your collection's contract has been registered, you can begin minting. Here's a summary of things to be aware of:
- On-chain properties — If your contract contains on-chain properties, ensure they are passed into the mint function's blueprint metadata, as those are the only extra values the
mintForreceives during withdrawal.
- Base URI — As mentioned earlier, consider what data needs to be on-chain if the asset is withdrawn. To include a property on-chain, often a base URI will be used so the rest of the data can still be retrieved without having it all on-chain.
- Asset IDs cannot be changed — When minting, you will set the IDs for your assets, but note that they cannot be changed later.
- Minting throughput — We recommend doing more mints per minting request over multiple minting requests with fewer mints per request. There is no restriction on the volume of concurrent minting requests, however, you should handle http status code
429(too many requests) with a sensible retry mechanism.
Updated 3 days ago