1

How do I fix this error/what might be causing it? I'm trying to have a user use their wallet to sign a partial transaction that I built on my backend. WalletSendTransactionError: unknown signer: <pubkey from phantom wallet>

This the API call on the backend. Am I using the CandyMachine mint right? I want it to mint to the user's wallet that is being used on the frontend:

routes.post('/api/mintsong', async (req, res) => {
  const accountPubKeyStr = req.body.accountPubKeyStr;
  const userPubkey = new PublicKey(accountPubKeyStr);
  const artistPubKeyStr = req.body.artistPubKeyStr;
  const artistPubKey = new PublicKey(artistPubKeyStr);
  const candyMachineAddress = req.body.candyMachineAddress;
  
  const connection = new Connection(ENDPOINT)

  // Get the shop keypair from the environment variable
  const shopKeypair = authority;

  // Initialise Metaplex with our shop keypair
  const metaplex = Metaplex
    .make(connection)
    .use(keypairIdentity(shopKeypair));

  const candyMachine = await metaplex.candyMachines().findByAddress({ address: new PublicKey(candyMachineAddress) });

  let deleteCandyMachine = false;
  if (candyMachine.itemsRemaining.toNumber() <= 1) {
    deleteCandyMachine = true;
  }

  const transactionBuilder = await metaplex.candyMachines().builders().mint({
    candyMachine: candyMachine,
    collectionUpdateAuthority: shopKeypair.publicKey,
    guards: {
      thirdPartySigner: {
        signer: shopKeypair,
      }
    }
  });

  
  // Create a guest identity for buyer, so they will be a required signer for the transaction
  const identitySigner = new GuestIdentityDriver(userPubkey);


  // Convert to transaction
  const latestBlockhash = await connection.getLatestBlockhash();
  const mintTransaction = await transactionBuilder.toTransaction(latestBlockhash);

  // Partially sign the transaction, as the shop and the mint
  // The account is also a required signer, but they'll sign it with their wallet after we return it
  mintTransaction.sign(shopKeypair);
  

  // Serialize the transaction and convert to base64 to return it
  const serializedTransactionMint = mintTransaction.serialize({
    requireAllSignatures: false // account is a missing signature
  });

  const base64Mint = serializedTransactionMint.toString('base64');

  // Return the serialized transaction
  res.send({
    transactionMint: base64Mint,
    deleteCandyMachine: deleteCandyMachine,
  });
});

Here is the frontend:

async function mintSong(e: React.MouseEvent) {
        e.preventDefault();
        if (!publicKey) return;

        // Get these two from DB
        const candyMachineAddr = 'addr';
        const songPrice = 0.9;  // 0.9 USDC

        // TODO: ADD CHECK FOR PRICE AND CALL THE WALLET TO CHECK IF THEY HAVE ENOUGH TO PAY

        // Fetch transaction from backend by sending connected wallet as 'account'
        fetch('http://localhost:3333/api/mintsong', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ 
                accountPubKeyStr: publicKey.toString(),
                candyMachineAddress: candyMachineAddr,
            })
        }).then(response => response.json())
        .then(async response => {
          const mintTransaction = Transaction.from(Buffer.from(response.transactionMint, 'base64'));
            try {
                await sendTransaction(mintTransaction, connection);
                if (response.deleteCandyMachine) {
                    fetch('http://localhost:3333/api/deleteCandyMachine', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({ 
                            candyMachineAddress: candyMachineAddr,
                        })
                    });
                }
                alert('Purchase complete!');
            } catch (error) {
                console.error(error);
                alert(`Error sending transaction: ${error}`);
            }
        })
        .catch(error => {
          console.error(error);
        });
    }

0

Your Answer

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