5

I cannot send the transaction here. Tried using wallet-adapter methods as well as solana/web3js methods, tried separating sendTransaction and confirmTransaction. Similar "cannot read .toString() of undefined" error for all the methods but at different places in the module.

Code

  const { connection } = useConnection();
  const wallet = useWallet();
  const burnAndSendSol = async () => {
    const associatedAddress = await getAssociatedTokenAddress(
      ASSOCIATED_TOKEN_PROGRAM_ID,
      TOKEN_PROGRAM_ID,
      mintPublickey,
      publicKey
    );

    const burnInstruction = createBurnCheckedInstruction(
      associatedAddress,
      mintPublickey,
      publicKey,
      1,
      TOKEN_PROGRAM_ID
    );

    const burnAndTransferTransaction = new Transaction().add(
      burnInstruction,
      SystemProgram.transfer({
        fromPubkey: publicKey,
        toPubkey: vaultPubKey,
        lamports: 0.5 * LAMPORTS_PER_SOL,
      })
    );

    try {
      const txn = await sendAndConfirmTransaction(
        connection,
        burnAndTransferTransaction,
        [wallet]
      );
    } catch (error) {
      console.log(error);
    }
  }

Error Stacktrace

TypeError: Cannot read properties of undefined (reading 'toString')
    at eval (index.browser.esm.js?156f:2629:1)
    at Array.forEach (<anonymous>)
    at Transaction.compileMessage (index.browser.esm.js?156f:2628:1)
    at Transaction._compile (index.browser.esm.js?156f:2749:1)
    at Transaction.sign (index.browser.esm.js?156f:2854:1)
    at Connection.sendTransaction (index.browser.esm.js?156f:7386:1)
    at async sendAndConfirmTransaction (index.browser.esm.js?156f:3130:1)
1
  • Presuming that my answer below is not the solution, we're going to need to know which toString() is failing. Either turn on sourcemaps in your project so that we get actual line numbers, or edit the implementation of Transaction.compileMessage() in your source to debug which toString() call is being called on undefined. Commented Aug 16, 2022 at 20:23

2 Answers 2

3

Presuming that useWallet() is from @solana/wallet-adapter, its return value is not a Signer.

The return value of useWallet is a WalletContextState.

WalletContextState does not expose the private key you would need to sign a transaction, as your code is currently written to do. Rather, use the methods returned by useWallet to send the transaction through the currently connected wallet.

const {sendTransaction} = useWallet();
const burnAndSendSol = useCallback(async () => {
  /* ... */
  try {
    const signature = sendTransaction(
      burnAndTransferTransaction,
      connection,
    );
    await connection.confirmTransaction(signature);
  } catch (e) {
    console.log(e);
  }
}, [sendTransaction]);

2

I found the solution and turns out it was just a rookie mistake on my side.

The mintPublicKey I was passing to the "getAssociatedAddress" function was the mint address in the string form instead of the PublicKey form, no wonder .toString() could not be called on it.

const mintPublicKey = new PublicKey(mintAddresss);

and passing mintPublicKey to getAssociatedAddress solved the issue.

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.