4

I am trying to use connection.sendEncodedTransaction() to send a signed Tx encoded to base64 like this:

const base64Tx = signedTransaction.serialize().toString('base64');
console.log('encodedTx:', base64Tx);

It has always worked but I have started converting my Txs to Versioned Transactions and now it seems to me that .toString('base64') is not working correctly or at all. This is what I get when dumped to the console:

encodedTx: 1,182,52,43,229,165,33,87,184,244,22,29,61,150,201,94,218,121,248,62,231,111,38,205,167,132,183,129,74,200,228,24,242,66,89,139,69,26,71,152,197,49,95,56,17,228,186,107,33,200,223,165,242,23,56,66,71,...

Then connection.sendEncodedTransaction() throws this error, which makes sense:

Error: failed to send transaction: InvalidByte(1, 44)
    at Connection.sendEncodedTransaction
    at async onStartTransaction

The error sometimes is a bit different:

Error: failed to send transaction: InvalidLength
    at Connection.sendEncodedTransaction
    at async onStartTransaction

Obviously the resulting encodedTx is not base64. I have also tried some standalone methods for converting Uint8Array to base64 and use the resulting string to send it and it works but I just don't want to use more libraries or handcrafted methods for something so simple that it should work. My guess is that I am probably missing something I should understand prior to moving to V0 Txs but I can't figure out whats happening.

Any help, north or headlights towards the possible solution would be greatly appreciated. Hopefully it is something simple or even my mistake and others falling into the same issue can have their answers too.

1 Answer 1

5

serialize on a versioned transaction gives Uint8Array, whereas on a legacy transaction you get a Buffer. Buffer supports base64 conversion, but Uint8Array doesn't. There's a utility function to convert the Uint8Array to Buffer:

import {Buffer} from 'buffer';
export const toBuffer = (arr: Buffer | Uint8Array | Array<number>): Buffer => {
  if (Buffer.isBuffer(arr)) {
    return arr;
  } else if (arr instanceof Uint8Array) {
    return Buffer.from(arr.buffer, arr.byteOffset, arr.byteLength);
  } else {
    return Buffer.from(arr);
  }
};

Call this on your serialized versioned transaction, then you can do toString('base64') on it.

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.