SolMeet
Search…
A Complete Guide to Mint Solana NFTs with Metaplex
Author: @ironaddicteddog
[Updated at 2022.4.27]
See the example repo here

Overview

  • Generate profile pictures (pfp) from trait materials with configurable weights
  • Use Metaplex Standard
  • Upload pfp and metadata to Arweave, which is a decentralized storage network
  • Mint NFT on solana-mf, a mainnet-fork developed by Dappio
  • Some handy tools
    • hashlips_art_generator
    • arweave-image-uploader
    • metaboss

Introduction to Metaplex

  • What does Metaplex do?
    • Metaplex Standard is adopted by popular wallets such as Phantom
  • What is in Metaplex standard?
    • See here for more details

Setup

Structure

1
├── 📂 solmeet-3-sandbox
2
3
├── 📂 hashlips_art_engine
4
│ │
5
│ ├── 📂 layers
6
│ │
7
│ └── 📂 build
8
│ │
9
│ ├── 📂 images
10
| |
11
| └── 📄 _metadata.csv
12
13
├── 📂 arweave-image-uploader
14
│ │
15
│ └── 📂 public
16
│ |
17
│ ├── 📂 images
18
│ |
19
│ ├── 📄 data.csv
20
│ |
21
│ └── 📄 arweave-uris.json
22
23
└── 📂 mint
24
25
├── 📄 mint.js
26
27
└── 📄 mints.json
Copied!

This Tutorial Only Works on x86_64 Chip

See here for more discussion and work arounds
This tutorial only works on x86_64 chip and does not work on Apple Sillicon (M1 Chip). Some C++ libraries (ex: cairo) may fail. If you are on M1 chip, I strongly recommend you to use a Linux VPS. Here are some options:

Install rust

Install solana

Download solmeet-3-sandbox

Option 1: Use Google Drive Web

Folder link here

Option 2: Use gdown (For Ubuntu User)

Install gdown:
1
$ sudo apt update
2
$ sudo apt install python3-pip
3
...
4
5
$ pip install gdown
6
...
Copied!
Download background, base, clothes, faces, hats separately:
1
$ mkdir solmeet-3-sandbox
2
$ cd solmeet-3-sandbox
3
$ gdown --folder https://drive.google.com/drive/folders/1RLz4J7TTh9cnXKWJlUb6_SC5dSnDYiBL -O background
4
...
5
6
$ gdown --folder https://drive.google.com/drive/folders/1jj4V7GNvFqc2UROZhaEvoaF1t8vP53TF -O base
7
...
8
9
$ gdown --folder https://drive.google.com/drive/folders/1FXuztlvSfIsStFXu4_dInXwV9xz_b-gz -O clothes
10
...
11
12
$ gdown --folder https://drive.google.com/drive/folders/1TM5zK9pHm73oSO1U8hpg6G1An14cyagU -O faces
13
...
14
15
$ gdown --folder https://drive.google.com/drive/folders/1GKYw77k0gQRX-AbtTtNChzpGsCBNL1bJ -O hats
16
...
Copied!

Option 3: Use scp

Download the folder to local machine first
1
$ scp -r [path of the local folder] [email protected]:[path to s]
Copied!

Install hashlips_art_engine

  • https://github.com/HashLips/hashlips_art_engine
1
$ git clone https://github.com/HashLips/hashlips_art_engine.git
2
...
3
4
$ cd hashlips_art_engine
5
$ yarn
6
...
Copied!
Notice: Make sure your node version >= v16.13.0. See this issue for more details.

Install arweave-image-uploader

  • https://github.com/thuglabs/arweave-image-uploader
1
$ git clone https://github.com/thuglabs/arweave-image-uploader.git
2
...
3
4
$ cd arweave-image-uploader
5
$ yarn
6
...
Copied!

Install metaboss

  • https://github.com/samuelvanderwaal/metaboss
1
$ sudo apt-get install pkg-config libssl-dev libudev-dev
2
...
3
4
$ cargo install metaboss --locked
5
...
Copied!

Install proxyman

  • https://proxyman.io/release/osx/Proxyman_latest.dmg
This should be installed on your local machine.
For Linux / Windows developers, you could choose whistle (open source) or postman.

Setup Arweave Wallet

Follow this doc to setup your Arweave wallet and claim free AR token by completing assigned task.
You should have a downloaded key file after the setup. We will need the keyfile in the rest of the tutorial.

Part 1: Generate Art Works

Modify hashlips_art_engine

Additionally, we have to make a few small changes in the codebase to export the data with desired format.
Next, replace the source code of hashlips_art_engine/src/main.js with the code from the example.
Here are the changes we made:
1
// In src/main.js
2
3
...
4
5
// Line 33
6
let traits = layerConfigurations[0].layersOrder.map(o => o.name);
7
let metadataListCsv = [`Name,${traits.join(",")}`];
8
...
9
10
// Line 171
11
metadataListCsv.push(`${tempMetadata.name.split('#')[1]},${attributesList.map(o => o.value).join(",")}`);
12
...
13
14
// Line 317
15
const writeMetaDataCsv = (_data) => {
16
fs.writeFileSync(`${buildDir}/_metadata.csv`, _data);
17
};
18
...
19
20
// Line 441
21
writeMetaDataCsv(metadataListCsv.join('\n'));
22
...
Copied!

Config hashlips_art_engine

Replace the source code of hashlips_art_engine/src/config.js with the code from the example.
Here are the changes we made:
1
// In src/config.js
2
3
...
4
5
// Line 5
6
const network = NETWORK.sol;
7
...
8
9
// Line 8
10
const namePrefix = "";
11
...
12
13
// Line 25
14
const layerConfigurations = [
15
{
16
growEditionSizeTo: 10,
17
layersOrder: [
18
{ name: "background" },
19
{ name: "base" },
20
{ name: "clothes" },
21
{ name: "faces" },
22
{ name: "hats" },
23
],
24
},
25
];
26
...
Copied!

Build Images

Copy solmeet-3-sandbox to hashlips_art_engine:
1
$ cd hashlips_art_engine
2
$ rm -rf ./layers
3
$ cp -r ../solmeet-3-sandbox ./layers
Copied!
Set the rarity for each trait by adding a weight number in filename. In this tutorial, we will keep every value the same weight in a certain trait.
After updating the filenames, you should have the following results:
1
$ ls layers/background
2
bg1#1.png bg2#1.png bg3#1.png bg4#1.png bg5#1.png
3
4
$ ls layers/base
5
base1#1.png base2#1.png
6
7
$ ls layers/clothes
8
clothes1#1.png clothes2#1.png clothes3#1.png clothes4#1.png clothes5#1.png
9
10
$ ls layers/faces
11
face1#1.png face2#1.png face3#1.png face4#1.png face5#1.png
12
13
$ ls layers/hats
14
hat1#1.png hat2#1.png hat3#1.png hat4#1.png hat5#1.png
Copied!
Finally, build the images:
1
$ yarn run build
Copied!
This will export the images to images folder and a _metadata.csv file, both under build folder.
Note: You can compute the distribution of rarity by this command:
1
$ yarn run rarity
Copied!

Part 2: Upload to Arweave

Setup Arweave Wallet

Follow this doc to setup your Arweave wallet and claim free AR token by completing assigned task.
You should have a downloaded key file after the setup. We will need the keyfile in the rest of the tutorial.

Modify arweave-image-uploader

Install dotenv:
1
$ yarn add dotenv
Copied!
Copy the whole string from the downloaded key file and paste to new .env file:
1
$ touch .env
Copied!
1
// In .env
2
3
KEY={"kty":"RSA","n":"tS1op66z_hQcHj5rKo_WZPvQp3nUP-auQCHqMr..."}
Copied!
Replace the source code of arweave-image-uploader/uploader.js with the code from the example.
Here are the changes we made:
1
// In uploader.js
2
3
...
4
5
// Line 6
6
import dotenv from "dotenv";
7
dotenv.config();
8
...
9
10
// Line 21
11
const getNftName = (name) => `SolMeet-3 ART #${name}`;
12
13
const getMetadata = (name, imageUrl, attributes) => ({
14
name: getNftName(name),
15
symbol: "SMT",
16
description:
17
"SolMeet #3 Art Work",
18
seller_fee_basis_points: 100,
19
external_url: "https://solmeet.dev",
20
attributes,
21
collection: {
22
name: "SolMeet",
23
family: "Dev",
24
},
25
properties: {
26
files: [
27
{
28
uri: imageUrl,
29
type: "image/png",
30
},
31
],
32
category: "image",
33
maxSupply: 0,
34
creators: [
35
{
36
address: "DaPYbGagq3dFDZ1i2PWpSP27mg1ty7J3XfQQciQPLsUn",
37
share: 100,
38
},
39
],
40
},
41
image: imageUrl,
42
});
43
...
44
45
// Line 93
46
let key = JSON.parse(process.env.KEY);
47
...
48
49
// Line 123
50
let metadataUri = [];
51
let metadataCollectionUri = [];
52
...
53
54
// Line 181
55
metadataUri.push(metadataUrl);
56
...
57
58
// Line 192
59
60
// Collection
61
const collectionFilePath = folder + "logo.png";
62
const collectionLogo = fs.readFileSync(collectionFilePath);
63
const contentType = ["Content-Type", "image/png"];
64
const { id } = await runUpload(collectionLogo, contentType, true);
65
const imageUrl = id ? `https://arweave.net/${id}` : undefined;
66
const collectionName = "SolMeet NFT DAO";
67
const collectionFamily = "DAO";
68
const metadata = getCollectionMetadata(
69
collectionName,
70
collectionFamily,
71
imageUrl
72
);
73
const metaContentType = ["Content-Type", "application/json"];
74
const metadataString = JSON.stringify(metadata);
75
const { id: metadataId } = await runUpload(metadataString, metaContentType);
76
const metadataUrl = id ? `https://arweave.net/${metadataId}` : undefined;
77
78
console.log("metadataUrl", metadataUrl);
79
const newItem = {
80
collection: {
81
name: collectionName,
82
uri: metadataUrl,
83
},
84
};
85
metadataCollectionUri.push(metadataUrl);
86
87
metadataCollection = { ...metadataCollection, ...newItem };
88
...
89
90
// Line 227
91
const uris = JSON.stringify(metadataUri);
92
fs.writeFileSync("./public/arweave-uris.json", uris);
93
const collectionUris = JSON.stringify(metadataCollectionUri);
94
fs.writeFileSync("./public/arweave-collection-uris.json", collectionUris);
95
...
Copied!
Notice: make sure that the address of creators is the same as the mint transaction sender, which is the Solana cli wallet. You can double check via this command:
1
$ solana address
2
DaPYbGagq3dFDZ1i2PWpSP27mg1ty7J3XfQQciQPLsUn
Copied!

Upload Images

Copy the images and metadata to arweave-image-uploader:
1
$ cd arweave-image-uploader
2
$ rm -rf public/images
3
$ cp -r ../hashlips_art_engine/build/images public/images
4
$ cp ../hashlips_art_engine/build/_metadata.csv public/data.csv
Copied!
Upload to Arweave:
1
$ yarn run upload
2
...
Copied!
After uploading, you should see a output file arweave-uris.json under public folder. This is the uris of all the metadata. We will soon use it for minting in the next step.
Also, you can access your image and metadata by visiting the uri. For example:
  • https://arweave.net/hcekmHUHRlQhTHSh0wc0m7zL_EyUahr_IjGlBk-4EO8
  • https://viewblock.io/arweave/tx/hcekmHUHRlQhTHSh0wc0m7zL_EyUahr_IjGlBk-4EO8

Part 3: Mint NFTs

Config Solana

Here, we use solana-mf for deploying and testing:
1
$ solana config set --url https://rpc-mainnet-fork.dappio.xyz
2
...
3
4
$ solana config set --ws wss://rpc-mainnet-fork.dappio.xyz/ws
5
...
Copied!
Don't forget to request for airdrop at the first place:
1
$ solana airdrop 1
2
...
Copied!

Mint

We will use metaboss for interacting with Metaplex. Here we have to do 3 things in order:
  • Create Collection
  • Mint NFTs
  • Set and verify the Collection for NFTs
First, create a folder mint an empty file mint.js:
1
$ mkdir mint
2
$ cd mint
3
$ touch mint.js
Copied!
Next, replace the source code of mint/mint.js with the code from the example.
Then, run the minting script:
1
$ KEYPAIR=~/.config/solana/id.json RECEIVER=MY_ADDRESS AUTHORITY=MY_ADDRESS node mint.js
2
3
collectionMint: 6NyVbJX1TB9HMYs5Wfx7qDuPcj8gX55DgsPh97Fv3M8T
4
nftMint: 6ofefmhENgvXwPznjJikZiAsbEKbxZb689gtkRcR4gUu
5
nftMint: HicQBruRwJHr7peuzAvZyhUrmwAAYXppjX1VQNVF15CC
6
nftMint: 2h7rHru4WRzBJnw3M7dN8TSfoUZPnzqD1Beo53gm6pC9
7
nftMint: 8vD2rNDNs6VZ7H4cRuRmi7uwZEff2MXxMA1Cbq9KdTm1
8
nftMint: 747BYudqdx9zdvwhvwvn5j4MDekpsuv9dEL5zNewcfvt
9
nftMint: C9pVfJRZR1NspdRAyPkow553aynNDpLnFYqBWZD5mWT9
10
nftMint: EYKc62HiRwKADAYe5fSTXXFfU5B5XCLg8nSsJACMEcGj
11
nftMint: 2U3pGSVSpVUYcaz3bu4ZMaDpHQjpXLVHnx6FbzzS5TJa
12
nftMint: EvT3voPJNZTTBTYvQYFmgboj9JxEnJiQ5zxr45tX5MKY
13
nftMint: 5H87TEVxeAK5kYiDP9UCzF3kCQ8L6rx263gqWBy4B1An
Copied!
The results can be found in mint/mints.json as well.

Display NFTs in Phantom

Config proxyman for redirecting the http requests that are sent to testnet. This is a hack for customizing Phantom RPC endpoint.
Open proxyman and press option + command + r to set the Map Remote rules:
Here, we redirect every requests to https://rpc-mainnet-fork.dappio.xyz, which is a solana-mf RPC operated by Dappio.
Note: make sure you are not running any VPN software other than Proxyman in order to make the mapping work.
Change the network to testnet in Phantom:
Now, the NFTs should all be displaying:
That's it!

Reference

General

  • https://github.com/ilmoi/awesome-solana-nfts
  • https://hackmd.io/@levicook/HJcDneEWF

Metaplex

  • https://medium.com/metaplex/metaplex-metadata-standard-45af3d04b541
  • https://medium.com/coinmonks/structure-of-metaplex-nft-c6ef4834a803
  • https://github.com/metaplex-foundation/metaplex-program-library/tree/master/token-metadata

Arweave

  • https://pencilflip.medium.com/how-to-use-arweave-to-store-and-access-nft-metadata-823552293f62
  • https://pencilflip.medium.com/how-to-use-arweave-to-store-and-access-nft-metadata-part-2-21cb87f4091e
tags: notes