Skip to content

Instantly share code, notes, and snippets.

@h4rkl
Last active October 9, 2023 20:15
Show Gist options
  • Save h4rkl/d527d923b24f1dd18d2829586a8f122c to your computer and use it in GitHub Desktop.
Save h4rkl/d527d923b24f1dd18d2829586a8f122c to your computer and use it in GitHub Desktop.
Test mint API for cNFT via helius
import prisma from "../../../lib/prisma";
import {
Metaplex,
walletAdapterIdentity,
bundlrStorage,
toMetaplexFile,
JsonMetadata,
} from "@metaplex-foundation/js";
import { Connection, Keypair } from "@solana/web3.js";
import { NextApiHandler } from "next";
import { MIXTAPE_COLLECTION } from "../../utils/nft";
import { Helius } from "helius-sdk";
import { getCluster } from "../../../scripts/helpers";
import { NftTemplate } from "@prisma/client";
export interface MintNFT {
template: NftTemplate;
nftImageBlob: string;
nftMetadata: JsonMetadata;
publicKey: string;
}
const mint: NextApiHandler = async (req, res) => {
if (req.method !== "POST") {
return res.status(405).json({ error: "Method not allowed" });
}
const { nftImageBlob, nftMetadata, template, publicKey } =
req.body;
const errors = {
nftImageBlob: !nftImageBlob && "NFT image is required",
nftMetadata: !nftMetadata && "NFT metadata is required",
template: !template && "NFT template is required",
publicKey: !publicKey && "Your Solana Wallet Public Key is required",
};
for (const [key, value] of Object.entries(errors)) {
if (value) {
return res.status(400).json({ error: value });
}
}
try {
const url = process.env.NEXT_PUBLIC_SOLANA_NETWORK!;
const connection = new Connection(url, "finalized");
const keys = JSON.parse(process.env.NEXT_KEYPAIR!);
const keysUint8Array = new Uint8Array(keys);
const mintKeys = Keypair.fromSecretKey(keysUint8Array);
const helius = new Helius(process.env.NEXT_HELIUS_RPC_KEY!, getCluster());
const metaplex = new Metaplex(connection);
metaplex.use(walletAdapterIdentity(mintKeys)).use(
bundlrStorage({
address: process.env.NEXT_PUBLIC_ARWEAVE_URL,
timeout: 60000,
identity: mintKeys,
})
);
const imageType = nftImageBlob.split(";")[0].split(":")[1];
const uploadNFTImage = async (base64Data: string) => {
const base64Image = base64Data.split(";base64,").pop();
if (!base64Image) {
throw new Error("Failed to extract base64 image data");
}
const buffer = Buffer.from(base64Image, "base64");
const imageFile = toMetaplexFile(buffer, template.name, {
extension: imageType.split("/")[1],
contentType: imageType,
});
const imageUpload = await metaplex?.storage().upload(imageFile);
if (!imageUpload) throw new Error("Image upload failed");
return imageUpload;
};
const imageAddress = await uploadNFTImage(nftImageBlob);
nftMetadata?.properties?.files?.push({
uri: imageAddress,
type: imageType,
});
// Retrieve the last record from prisma for mint and increment the id
const lastMint = await prisma.mint.findFirst({
orderBy: {
id: "desc",
},
});
const metaName = lastMint ? `MixtApe #${lastMint.id + 1}` : `MixtApe`;
nftMetadata.name = metaName;
const metadata = await metaplex?.nfts().uploadMetadata(
{
...nftMetadata,
image: imageAddress + `?ext=${imageType}`,
type: imageType,
payer: mintKeys.publicKey,
},
{ commitment: "finalized" }
);
if (!metadata) throw new Error("Metadata upload failed");
console.log(metadata, imageAddress);
const transaction = await helius.mintCompressedNft({
owner: publicKey,
name: nftMetadata.name,
symbol: nftMetadata.symbol,
description: nftMetadata.description,
delegate: nftMetadata.properties?.creators?.[0].address,
// collection: MIXTAPE_COLLECTION.toBase58(),
creators: nftMetadata.properties?.creators,
uri: metadata.uri,
sellerFeeBasisPoints: nftMetadata.properties?.seller_fee_basis_points,
imageUrl: imageAddress + `?ext=${imageType}`,
externalUrl: "",
attributes: nftMetadata.properties?.attributes,
});
console.log(transaction);
// await prisma.mint.create({
// data: {
// mintAddress,
// nftMetadata: JSON.parse(JSON.stringify(nftMetadata)),
// signature: signature,
// // location,
// userId: user.id,
// templateId: template.id,
// },
// });
return res.status(200).json({ mintAddress: transaction });
} catch (error) {
console.log(error);
return res.status(500).json({ error: (error as Error).message });
}
};
export default mint;
import type { NextApiRequest, NextApiResponse } from "next";
import { Helius } from "helius-sdk";
import { getCluster } from "../../../../scripts/helpers";
const helius = new Helius(process.env.NEXT_HELIUS_RPC_KEY!, getCluster());
async function getNFTMetadata(nftId: string) {
const nft = await helius.rpc.getAsset(nftId);
console.log("******", helius, getCluster());
return nft.content?.metadata;
}
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method !== 'GET') {
return res.status(405).json({ error: "Method not allowed" });
}
const { address } = req.query;
if (!address) {
return res.status(400).json({ error: "Missing NFT id" });
}
try {
const data = await getNFTMetadata(address as string);
res.status(200).json({ metadata: data });
} catch (error) {
res.status(500).json({ error: "Failed to fetch NFT metadata" });
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment