2

How would I go about converting the following testing code (from an anchor project) to something that would interact with my frontend in production (or convert it into a function to be used in react when a user submits a form)? I'm confused about/want to confirm the following:

wallet should be set to the user's wallet, which they would via a 'connect wallet' button.
program what should I change this to/how would I access a program that is existing on the blockchain. What I'm asking is given the address of a program, how do I interact with it?
nftMint what is the difference between this keypair and the wallet? What is this necessary for and would I still use `anchor.web3.Keypair.generate()?

For production code, are there any checks or require statements that I should put into my code to ensure that everything is working properly/to prevent bad actors (similar to how one might use require statements in Solidity)?

import * as anchor from "@project-serum/anchor"
import * as spl from "@solana/spl-token"
import { Program } from "@project-serum/anchor"
import { MintSongNft } from "../target/types/mint_song_nft"
import { Metaplex } from "@metaplex-foundation/js"
import {
  Metadata,
  PROGRAM_ID as TOKEN_METADATA_PROGRAM_ID,
} from "@metaplex-foundation/mpl-token-metadata"
import { assert } from "chai"

describe("mint-nft", () => {
  // Configure the client to use the local cluster.
  anchor.setProvider(anchor.AnchorProvider.env())

  const program = anchor.workspace.MintSongNft as Program<MintSongNft>
  const wallet = anchor.workspace.MintSongNft.provider.wallet
  const connection = program.provider.connection
  const metaplex = Metaplex.make(connection)

  const testMetadata = {
    uri: "https://arweave.net/h19GMcMz7RLDY7kAHGWeWolHTmO83mLLMNPzEkF32BQ",
    name: "NAME",
    symbol: "SYMBOL",
  }


  it("Is initialized!", async () => {
    const [pda] = anchor.web3.PublicKey.findProgramAddressSync(
      [Buffer.from("nft")],
      program.programId
    )

    const nftMint = anchor.web3.Keypair.generate()

    const metadata = await metaplex
      .nfts()
      .pdas()
      .metadata({ mint: nftMint.publicKey })

    const masterEdition = await metaplex
      .nfts()
      .pdas()
      .masterEdition({ mint: nftMint.publicKey })

    const tokenAddress = await spl.getAssociatedTokenAddress(
      nftMint.publicKey,
      wallet.publicKey
    )

    // Add your test here.
    const txSig = await program.methods
      .mintNft(testMetadata.uri, testMetadata.name, testMetadata.symbol)
      .accounts({
        payer: wallet.publicKey,
        pda: pda,
        nftMint: nftMint.publicKey,
        metadata: metadata,
        masterEdition: masterEdition,
        tokenAccount: tokenAddress,
        tokenMetadataProgram: TOKEN_METADATA_PROGRAM_ID,
      })
      .signers([nftMint])
      .rpc()
    console.log("Your transaction signature", txSig)

    const accountInfo = await connection.getAccountInfo(metadata)
    const metadataData = Metadata.deserialize(accountInfo.data, 0)

    assert.ok(
      metadataData[0].data.uri.startsWith(testMetadata.uri),
      "URI in metadata does not start with expected URI"
    )
    assert.ok(
      metadataData[0].data.name.startsWith(testMetadata.name),
      "Name in metadata does not start with expected name"
    )
    assert.ok(
      metadataData[0].data.symbol.startsWith(testMetadata.symbol),
      "Symbol in metadata does not start with expected symbol"
    )

    assert.ok(
      metadataData[0].data.creators[0].address.equals(pda),
      "Creator is not PDA"
    )

    assert.ok(
      metadataData[0].data.creators[0].verified,
      "Creator is not verified"
    )

    assert.strictEqual(
      Number(
        (await connection.getTokenAccountBalance(tokenAddress)).value.amount
      ),
      1,
      "Token amount is not 1"
    )
  })
})

1 Answer 1

2

Regarding the wallet, yes, in a real client would be the user wallet, for example, here i define a provider to access that: https://github.com/JuanMarchetto/solana-4-in-line/blob/main/app/src/contexts/ClientWalletProvider.tsx

and here i'm using that: https://github.com/JuanMarchetto/solana-4-in-line/blob/main/app/src/pages/_app.tsx#L22

since i'm using nextJs that include the wallet in al my pages

Regarding the program one of the more common way to access one is having an idl file wich provides an interface to interact with it, here you have an example of hoe i tend to include a program IDL in my clients code:

https://github.com/JuanMarchetto/solana-4-in-line/blob/main/app/src/utils/useProgram.ts

and here you have an example of how i use it: https://github.com/JuanMarchetto/solana-4-in-line/blob/main/app/src/components/CreateGame/index.tsx#L33

regarding the use of the const nftMint in the code you shared they are generating a wallet in that moment to use it, i recommend you to read the docs for the program you are interacting with to understand if that is in fact what you will need to do (simply generating a new wallet) or if that is something that you need to have in advance somehow

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.