I made TypeScript code where I could make an NFT using an image-link as the metadata (taking help from the Solana Stack Exchange site). Now. When I tried to implement it in my frontend, I was getting errors.
const metaplex = Metaplex.make(connection)
.use(keypairIdentity(user))
.use(
bundlrStorage({
address: "https://devnet.bundlr.network",
providerUrl: "https://api.devnet.solana.com",
timeout: 60000,
})
)
The problem is that in use(keypairIdentity(user))
user is a Keypair, i.e., both the public key and private key. However, when making the frontend, I am unable to access the private key. So. I am unsure of how to go with this.
Here is the full code:
export const CreateNFT: FC = () =>
{
const { connection } = useConnection();
const { publicKey } = useWallet();
const onClick = useCallback(async () => {
if (!publicKey) throw new Error("No wallet connected"); // Corrected: throw a new Error object instead of WalletNotConnectedError
// rent for token mint
const lamports = await getMinimumBalanceForRentExemptMint(connection);
// keypair for new token mint
const mintKeypair = Keypair.generate();
// get metadata PDA for token mint
const metadataPDA = await findMetadataPda(mintKeypair.publicKey);
// get associated token account address for use
const tokenATA = await getAssociatedTokenAddress(
mintKeypair.publicKey,
publicKey // Use the public key from the web3 wallet
);
// Create a read-only Keypair object from the user's public key
const userKeypair = new Keypair({ publicKey });
const metaplex = Metaplex.make(connection)
.use(keypairIdentity(userKeypair)) // Corrected: use a Keypair object with the public key from the web3 wallet
.use(
bundlrStorage({
address: "https://devnet.bundlr.network",
providerUrl: "https://api.devnet.solana.com",
timeout: 60000,
})
);
// Upload the image file to Bundlr and get the URI for the uploaded file
const imageUri = await metaplex.storage().upload(imageFile); // Corrected: define and assign a value to the imageUri variable
// upload metadata and get metadata uri (off chain metadata)
const { uri } = await metaplex
.nfts()
.uploadMetadata({
name: tokenName,
description: description,
image: imageUri, // Corrected: use the imageUri variable
});
console.log("metadata uri:", uri);
// create NFT
async function createNft(
metaplex: Metaplex,
uri: string
): Promise<NftWithToken> {
const { nft } = await metaplex .nfts()
.create({
uri: uri,
name: tokenName,
sellerFeeBasisPoints: sellerFeeBasisPoints,
symbol: symbol,
});
console.log(
`Token Mint: https://explorer.solana.com/address/${nft.address.toString()}?cluster=devnet`
);
return nft;
}
await createNft(metaplex, uri);
}, [connection, publicKey]); // Make sure to include the connection and publicKey values in the dependency array
return (
<button onClick={onClick} disabled={!publicKey}>
Create NFT!
</button>
);
};
const userKeypair = new Keypair({ publicKey });
I tried creating a keypair, but of course it did not work.
How do I create a transaction that when signed by the user starts the whole process, etc.?