This guide covers deploying your first NFT on Solayer Devnet using decentralized storage via IPFS. Full code examples are available on GitHub.
Prerequisites
- Node.js (v18+) & npm installed
- Basic terminal knowledge
- Image file for your NFT
- For Intitial Enviornment Setup refer Hello Solayer guide.
Step 1: Project Setup
Create a dedicated project directory and initialize Node.js:
mkdir solayer-nft && cd solayer-nft
npm init -y
npm install dotenv
Set up your project structure and configure package.json
to use ES modules.
Step 2: Environment Configuration
Create .env.example
as a template:
# Example
PRIVATE_KEY=YOUR_PRIVATE_KEY
IPFS_URL=YOUR_IPFS_URL
Copy this to .env
and fill in your details securely.
The following code is a trimmed snippet from the full implementation available in the solayer-labs/solayer-devs GitHub repository.
It highlights only the core functionality—for example, reading NFT metadata, building Solana transactions, and minting the NFT. For complete logic including validation, logging, error handling, environment setup, and deployment indexing, please refer to the respective full files:
• scripts/deploy_nft.js
• config/index.js
• scripts/setup.js
Step 3: Configuration Module
Create config/index.js
to centrally manage settings.
import dotenv from 'dotenv';
import fs from 'fs';
import path from 'path';
dotenv.config();
// Fail fast if essential .env vars are missing
['SOLANA_RPC_URL', 'SOLANA_KEYPAIR_PATH']
.filter(v => !process.env[v])
.length && process.exit(1);
const expand = p => p.startsWith('~/')
? path.join(process.env.HOME, p.slice(2))
: p;
const config = {
solana: {
rpcUrl: process.env.SOLANA_RPC_URL,
keypairPath: expand(process.env.SOLANA_KEYPAIR_PATH),
commitment: 'confirmed'
},
nft: {
defaultMetadataFile: process.env.DEFAULT_METADATA_FILE || 'assets/nft-metadata.json'
},
validate() {
if (!fs.existsSync(this.solana.keypairPath)) throw new Error('Keypair not found');
return true;
},
display() {
console.log('RPC URL:', this.solana.rpcUrl);
console.log('Keypair:', this.solana.keypairPath);
}
};
export default config;
Step 4: Development Environment Validation
Automate checks using scripts/setup.js
.
import { execSync } from 'child_process';
import fs from 'fs';
import config from '../config/index.js';
(async () => {
// 1. Check Solana CLI
try { execSync('solana --version'); }
catch { console.error('Install Solana CLI'); process.exit(1); }
// 2. Ensure keypair exists
if (!fs.existsSync(config.solana.keypairPath)) {
execSync(`solana-keygen new --outfile ${config.solana.keypairPath} --no-bip39-passphrase`);
}
// 3. Configure CLI to Devnet
execSync(`solana config set --url ${config.solana.rpcUrl} --commitment confirmed`);
// 4. Airdrop if balance is zero
const bal = execSync('solana balance', { encoding: 'utf8' });
if (bal.startsWith('0')) execSync('solana airdrop 1');
// 5. Create sample metadata file if missing
if (!fs.existsSync(config.nft.defaultMetadataFile)) {
fs.writeFileSync(
config.nft.defaultMetadataFile,
JSON.stringify({ /* sample NFT metadata */ }, null, 2)
);
}
console.log('✅ Environment setup complete');
})();
Step 5: Upload NFT Image to IPFS
Create NFT metadata in assets/nft-metadata.json
:
{
"name": "Solayer Devnet NFT",
"symbol": "SLYR",
"description":" Testing NFT Deployment on Solayer Devnet!",
"image": "YOUR_IPFS_IMAGE_URL",
"attributes": [{"trait_type": "Network", "value": "Solayer"}]
}
Step 7: NFT Deployment
Create a deployment script scripts/deploy_nft.js
to:
- Read NFT metadata
- Set up blockchain transactions
- Mint NFT on Solayer Devnet
Below is a concise snippet of your deployment script (scripts/deploy_nft.js
) focusing on the core functions. The full implementation (initialization, transaction confirmation, index updates, error handling, etc.) is available in the GitHub repo.
import { Connection, Keypair, Transaction, SystemProgram, LAMPORTS_PER_SOL } from '@solana/web3.js';
import {
createInitializeMintInstruction,
createAssociatedTokenAccountInstruction,
createMintToInstruction,
getMinimumBalanceForRentExemptMint,
MINT_SIZE,
TOKEN_PROGRAM_ID,
getAssociatedTokenAddress
} from '@solana/spl-token';
import fs from 'fs';
import config from '../config/index.js';
async function deployNFT(metadataFilePath) {
// 1. Read and validate NFT metadata
const metadata = JSON.parse(fs.readFileSync(metadataFilePath, 'utf8'));
// 2. Connect to Solayer Devnet
const connection = new Connection(config.solana.rpcUrl, { commitment: config.solana.commitment });
const payer = Keypair.fromSecretKey(/* loaded from config */);
// 3. Create metadata URI (e.g., upload to IPFS)
const metadataUri = await createMetadataUri(metadata);
// 4. Generate mint keypair & associated token account
const mintKeypair = Keypair.generate();
const tokenAccount = await getAssociatedTokenAddress(mintKeypair.publicKey, payer.publicKey);
// 5. Build and send mint transaction
const rent = await getMinimumBalanceForRentExemptMint(connection);
const { blockhash } = await connection.getLatestBlockhash();
const tx = new Transaction({ recentBlockhash: blockhash, feePayer: payer.publicKey })
.add(
SystemProgram.createAccount({
fromPubkey: payer.publicKey,
newAccountPubkey: mintKeypair.publicKey,
space: MINT_SIZE,
lamports: rent,
programId: TOKEN_PROGRAM_ID
}),
createInitializeMintInstruction(mintKeypair.publicKey, 0, payer.publicKey, payer.publicKey),
createAssociatedTokenAccountInstruction(payer.publicKey, tokenAccount, payer.publicKey, mintKeypair.publicKey),
createMintToInstruction(mintKeypair.publicKey, tokenAccount, payer.publicKey, 1)
);
tx.sign(payer, mintKeypair);
// 6. Send transaction
const signature = await connection.sendRawTransaction(tx.serialize());
console.log('🎉 NFT minted! Signature:', signature);
}
export { deployNFT };
Step 7: Deploy NFT
node scripts/deploy_nft.js assests/nft-metadata-test.json
Step 8: (Optional) API Server
Deploy a local API server using server/api.js
to track and manage NFT deployments.
Check the guide on Github for additional steps to configure your server.
Step 9: Verification
Verify NFT deployment on Solayer Explorer using the deployment address.
Additional Resources & Support