Create 1 million (or more) NFTs with zero fees

Create 1 million (or more) NFTs with zero fees

The 0xcert Framework provides multiple functionalities, some of which were explained in previous tutorials. Today, we are going to focus on one particularly potent part, namely atomic operations. We purposely called them atomic operations, not atomic swaps. What is the reason?

Well, let's first take a look at the definition of an atomic swap. An atomic swap is defined as:

A smart contract technique then enables the transfer of an asset between two parties without using a centralized intermediary.

➡️ To learn more about atomic swaps, please check this article.

An atomic swap, as you can see, is what powers decentralized exchanges. But despite its potential, the same principals can be used in many other ways, as well.

This is where atomic operations come in, and these can be created within the 0xcert Framework as atomic orders. Currently, atomic operations in the 0xcert Framework can be used to create and update the state of NFTs, but there are many more operations that can ascend from it and will be supported in further iterations.

Now, how does an atomic operation allow us to create NFTs for free? It is by making atomic orders that can create NFTs.

This means that instead of creating a new NFT, you actually define an atomic order by describing the NFT you want to create and sign said order. The intended receiver of the NFT can then execute this order to claim the token, and by doing so, they end up paying the gas fee, not you. With this method, you can create an unlimited number of NFTs for free and delegate their creation cost to the receiver.

We call this delegate minting. This type of minting solves several problems for the creator of NFTs - instead of having to pay a bunch of ETH to create tokens, you (as a creator) just delegate the fees to the receiver; the receiver of the order, in turn, has the option to either execute the creation of NFT or not.

Creating an atomic order for delegate mint

In this tutorial, we will assume you already know the basics of the 0xcert Framework from our previous tutorials. In the introduction above, we talked about NFTs, but as mentioned in previous Framework tutorials, the NFTs are called assets within the 0xcert Framework.

Now, let's go through the steps of creating an atomic order for our purpose of minting a million NFTs with no gas fees. Working code example for this tutorial can be found here.

⚠️ But before we start, we need to set up a few things:

1. Deploy a new assetLedger or instantiate an existing assetLedger with you as the owner (having the super ability).
2. Allow orderGateway to create tokens for our assetLedger.
3. Specify the accounts that will have the ability to actually sign an atomic order for asset creation.

For this tutorial, we will assume you already have a development environment set up and that you are the owner of a deployed assetLedger. If you do not have this set up yet, please check our Documentation guide or previous tutorials.

✅ Now that we have everything ready, let's dive right in.

The first thing you need to do is to allow orderGateway to create new assets on your behalf. You do this by calling:

await assetLedger.grantAbilities(
  orderGateway, // instance of order gateway

Next, you need to specify who will be able to sign the atomic order that creates a new asset. Here's how:

await assetLedger.grantAbilities(
  '0x...', // account address (will be the maker od the order)

Once you grant these two abilities, you have everything ready to perform delegate mint. Granting of abilities only needs to be done once. After that, you can decide on creating as many orders of asset creation as you want - like so:

import { OrderGateway, Order, OrderActionKind } from '@0xcert/ethereum-order-gateway';
// Define atomic order
const order = {
   makerId: '0x...', // Maker address (must have ALLOW_CREATE_ASSET ability)
   takerId: '0x...', // Taker address (address that will perform the order)
   actions: [
           kind: OrderActionKind.CREATE_ASSET, // Set action type to create asset
           ledgerId: assetLedgerId, // ID of asset ledger where new asset will be created
           receiverId: '0x...', // Receiver address
           assetId: '200', // ID of asset to be created
           assetImprint: 'aa431acea5ded5d83ea45f1caf39da9783775c8c8c65d30795f41ed6eff45e1b', // Imprint of asset to be created
   seed:, // Unique order identification
   expiration: + 60 * 60 * 24 * 100, // 100 days
} as Order;
// Order Gateway address
const orderGatewayId = '0x0e4f45ad9bca9f214e73683f734f5b1aa3a4051a'; // Ropsten Order Gateway address
// Create an instance of Order Gateway
const orderGateway = OrderGateway.getInstance(provider, orderGatewayId);
// Sign the claim
const signedClaim = await orderGateway.claim(order);

At this point, the order is created an signed. What's best, it was done with precisely zero gas consumed. You are now ready to send the order and signedClaim to the Taker.

A Taker can perform the order and by such, create the token as such:

const orderGateway = OrderGateway.getInstance(provider, orderGatewayId);
const mutation = await orderGateway.perform(order, signedClaim);
await mutation.complete();

Marketplace - Any Taker

In the atomic order we created above, we defined both the takerId and receiverId. Another option that the 0xcert Framework provides is a dynamic order option that leaves takerId and receiverId undefined or sets them as null - this way, any account or wallet would have the ability to perform such order.

This option is perfect for creating a digital marketplace by defining asset creation in exchange for tokens (a single order can contain multiple actions). It allows you to simultaneously create an asset and sell it, all while paying zero fees in a single atomic transaction. This introduces the potential for even more powerful operations that expand the application possibilities of the 0xcert Framework.


In this mock-up case, we have demonstrated a way to create an unlimited amount of assets and paying zero gas fess in the process - more accurately, delegating the fees to the receiver. This method provides a number of possible use cases and prevents the network from having to execute a bunch of transactions at once.

We hope you enjoyed this and previous tutorials, and we'll be happy to hear what you came up with.

If, however, you're still stuck in the process and need a hand with checking your code, go and ask our developers in the 0xcert Gitter channel, they will be glad to help you build the next big decentralized thing.