Last active
October 9, 2023 20:15
-
-
Save h4rkl/d527d923b24f1dd18d2829586a8f122c to your computer and use it in GitHub Desktop.
Test mint API for cNFT via helius
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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