6

I've been trying to create & send transactions like this, but I'm getting SolanaError: JSON-RPC error: Invalid method parameter(s) (invalid base58 encoding: InvalidCharacter { character: '+', index: 12 })

  const transactionMessage = pipe(
    createTransactionMessage({ version: 0 }),
    (tx) => setTransactionMessageFeePayerSigner(kp, tx),
    (tx) =>
      setTransactionMessageLifetimeUsingBlockhash(
        { blockhash, lastValidBlockHeight },
        tx
      ),
    (tx) => appendTransactionMessageInstructions(instructions, tx),
    (m) => addSignersToTransactionMessage([kp, newAccountKp], m)
  );

  const tx = await pipe(compileTransaction(transactionMessage), (tx) =>
    signTransaction([kp.keyPair, newAccountKp.keyPair], tx)
  );

  const sig = rpc
    .sendTransaction(getBase64EncodedWireTransaction(tx), {
      skipPreflight: true,
    })
    .send();

2 Answers 2

6

The sendTransaction JSON-RPC method defaults to a base58 encoding: https://solana.com/docs/rpc/http/sendtransaction#parameters

You need to pass base64 encoding to override that:

  const sig = rpc
    .sendTransaction(getBase64EncodedWireTransaction(tx), {
      encoding: 'base64',
      skipPreflight: true,
    })
    .send();

Note that there is a simpler API that takes care of this for you: sendTransactionWithoutConfirmingFactory

const sendTransaction = sendTransactionWithoutConfirmingFactory({ rpc });
await sendTransaction(tx, { skipPreflight: true })

There is also sendAndConfirmTransactionFactory if you'd like to also use subscriptions to confirm the transaction has landed before continuing.

5

Found a solution. Turns out I needed to create sendAndConfirm via sendAndConfirmTransactionFactory.

const rpc = createSolanaRpc('http://127.0.0.1:8899');
const rpcSubscriptions = createSolanaRpcSubscriptions('ws://127.0.0.1:8900');
const sendAndConfirm = sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions });

const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
const message = pipe(
  createTransactionMessage({ version: 0 }),
  (m) => setTransactionMessageFeePayerSigner(feePayer, m),
  (m) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, m),
  (m) => appendTransactionMessageInstructions(instructions, m),
);

const signedTransaction = await signTransactionMessageWithSigners(message);

// Optional, to look up tx on explorers
const signature = getSignatureFromTransaction(signedTransaction);

await sendAndConfirm(signedTransaction, { commitment });

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.