# Offchain Minting Offchain minting is a feature built into the NFTs pallet. It is the ability to mint NFTs by having the issuer of a collection sign encoded mint data offchain, this encoded mint data will either designate the account that can mint the NFT or if any account can mint it. Once signed by the issuer, the enduser can mint the NFT via the `mint_pre_signed` extrinsic. When creating the mint data, a deadline is also specified (in the form of a block number). Once the deadline is reached, the signed encoded mint data expires and is no longer valid. Okay.. so how do we do this in Substrate? Let's get started. This guide will use PolkadotJS Apps to walk you through the process of offchain minting! First we have to create an NFT collection. ![](https://hackmd.io/_uploads/SJESZITSn.png) ![](https://hackmd.io/_uploads/r1gkGUTSn.png) Encoded call data: ``` 0x2a0000d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d0000000000000000010a000000000000000000000000000000 ``` Next we have to do three things: - create our mint data (this will be the NFT we want to be minted) - encode the mint data - sign the encoded mint data - the account that signs the encoded mint data should be an issuer for the collection, meaning, they have approval to mint > Note: when creating the mint data, if you only intend one account to have permission to mint that NFT then specify this in the `only_account` attribute otherwise, any account will be able to mint the NFT. We can use PolkadotJs Apps to construct the mint data like so: ![](https://hackmd.io/_uploads/Sk7lx86r2.png) ![](https://hackmd.io/_uploads/SyIEx8aS2.png) > We are not going to submit this transaction. We are only using it to obtain the encoded mint data. You could also construct this using JavaScript and PolkadotJS API or similar. Keep in mind that `onlyAccount` here is set to `None`. This means that any account that has access to this mint data, once it is signed, could mint this NFT. For `deadline` specify the block number where this transaction will be valid for. The transaction will be valid up to this block number. Notice the encoding details on the bottom right of the screen. From that we can concatenate and construct our encoded mint data: ``` 0x000000000000000004106e616d65304272756e6f2047616c76616f0000d0070000 ``` We now have to sign the encoded mint data. ![](https://hackmd.io/_uploads/HJce7LaHh.png) Alternatively, here is a nice script: ```js import { Keyring } from '@polkadot/keyring'; import { u8aToHex } from '@polkadot/util'; import { cryptoWaitReady } from '@polkadot/util-crypto'; export const sign = async () => { await cryptoWaitReady(); const keyring = new Keyring({ type: 'sr25519' }); const pair = keyring.addFromUri('//Alice'); const sig = pair.sign('0x000000000000000004106e616d65304272756e6f2047616c76616f0000d0070000'); console.log('Signature: ', u8aToHex(sig)); } ``` Output: ``` Signature: 0x163b1eb3420cf2b78b4ffedca11e9618dd8528e6e7485cb343379d9db6aa84305f9995b6bf2120d4541d36a9056f6a158ccc5e8745794657073ae23cb3de838f ``` We can now create the `mintPreSigned` extrinsic and include our signature: ![](https://hackmd.io/_uploads/Hkx5qRhSh.png) ![](https://hackmd.io/_uploads/ry_5sA2B3.png) Click "Submit Transaction" and you have now minted a crisp, fresh NFT. ![](https://hackmd.io/_uploads/By6_J8aH3.png) Success! Done. ## Resources Offchain Minting PR - https://github.com/paritytech/substrate/pull/13158 Test for offchain minting (super useful to read): - https://github.com/paritytech/substrate/blob/0cf64f8bd72d719818be2f109c0919c7c9325cd1/frame/nfts/src/tests.rs#L3171-L3337