I have a few questions that I have commented in the code included below that is meant to create a Candy Machine to mint song NFTs from. Note that all of the NFTs should be same (the only difference between them is the number in their name).

Aside from the questions in the code, here are a few other questions:

  • Once I have made the Candy Machine, where do I store it? Should I use a database that stores an artists pubkey and all of the Candy Machines associated to it or is there a better way to access this info?
  • How would I make this NFT programmable such that the royalties are enforced?
import { keypairIdentity, Metaplex, toBigNumber, token } from '@metaplex-foundation/js';
import { clusterApiUrl, Connection, Keypair, PublicKey } from '@solana/web3.js';

const connection = new Connection(clusterApiUrl('devnet'));
const metaplex = new Metaplex(connection);
const authority = createKeypairFromFileSync('devnet_keypair.json');  // Custom method that turns a keypair json into a Keypair object

routes.post('/api/testcandymachine', async (req, res) => {
  const { artistPubKey } = req.body.artistPubKey;  // From wallet connection
  const title: string = 'Title';
  const artist: string = 'Artist';
  const jsonAWSLocation = "https://<storage-name>.s3.amazonaws.com/<json-filename>.json";
  const { numCopies } = req.body.numCopies;
  const { priceOfSong } = req.body.priceOfSong;

  // PublicKey with USDC mint authority. What should I use here?
  const usdcPubKey = new PublicKey("2wmVCSfPxGPjrnMMn7rchp4uaeoTqN39mXFC2zhPdri9");

  const { nft: collectionNft } = await metaplex.nfts().create({
    name: `${title} - ${artist}`,
    uri: jsonAWSLocation,
    sellerFeeBasisPoints: 0,
    isCollection: true,
    updateAuthority: authority,

  const { candyMachine } = await metaplex.candyMachines().create({
    sellerFeeBasisPoints: 1000,  // 10.0%
    symbol: 'SYMBOL',
    maxEditionSupply: toBigNumber(0),
    isMutable: true,
    creators: [
      { address: req.body.artistPubKey, share: 100 },
      { address: authority.publicKey, share: 0 },  // Set my wallet as creator with 0% share
    collection: {
      address: collectionNft.address,
      updateAuthority: metaplex.identity(),
    itemsAvailable: toBigNumber(numCopies),
    itemSettings: {
      type: "configLines",
      prefixName: `${req.body.title} #$ID+1$`,
      nameLength: 0,
      prefixUri: jsonAWSLocation,
      uriLength: 0,
      isSequential: false,
    guards: {
      /* This guard enforces the price of the NFT in USDC. I want my wallet to be credited with the payment, but am not sure if my code is doing this properly */
      tokenPayment: {
        amount: token(priceOfSong),
        // mint: tokenMint.address,  // This is what the Metaplex docs recommend
        mint: usdcPubKey,
        destinationAta: metaplex.tokens().pdas().associatedTokenAccount({
          // mint: tokenMint.address,
          mint: usdcPubKey,
          owner: metaplex.identity().publicKey,
      /* Forces all transactions to be signed by the Tonic wallet */
      thirdPartySigner: {
        signerKey: authority.publicKey,

  const itemsToBeAdded = new Array(numCopies).fill({ name: '', uri: '' });

  // Will this work if I'm inserting upwards of 10,000 items?
  const resOfInsertingItems = await metaplex.candyMachines().insertItems({
    items: itemsToBeAdded,
  console.log(`Signature of item upload transaction: ${resOfInsertingItems.response.signature}`);

  res.send('Candy Machine Test Completed');


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.