Javascript Frontend communicating with Python Backend

I am trying to pass a transaction signed in the frontend using the js sdk to the backend, which is in Python, but the two objects don’t seem to be compatible and I can’t find the structure of the one for the signed transactions in python.

How should I carry on such a task? I want to send the signed transaction to the backend in order to perform the submission from the backend.

Thanks!

1 Like

Most objects on the Algorand blockchain are serialized in msgpack (more precisely in a slightly customized version of msgpack which produces canonical encodings and which removes empty fields). You can encode a transaction in msgpack with the JS SDK using: algosdk.encodeObj

You can then decode it with the Python SDK using: https://py-algorand-sdk.readthedocs.io/en/latest/algosdk/encoding.html#algosdk.encoding.msgpack_decode

Could you please give me a more guided flow?
I’m asking this because I followed your instructions but it still doesn’t work.

Let’s suppose I have the object in js signedTxn, I encoded it with algosdk.encodeObj as you suggested and I sent it to the backend.
There, I retrieved the data and used algod.encoding.msgpack_decode(enc_signed_tx), and finally:

tx_confirm = acl.send_transaction(signed_tx, headers={‘content-type’: ‘application/x-binary’})

This didn’t work, neither did when I stringified the encoded object before sending or after arrival to the backend.

If you could explain me further or provide an example that I can run from two terminals (one with NodeJs and the other with Python) that would be much appreciated :blush:

Thank you!

Here is an example.

The following JS code creates and signs a transaction, and export it as base64 (this is NodeJS, but you should be able to easily convert it to browser JS if you prefer - for that, you essentially will just need to replace Buffer... and require...):

const algosdk = require('algosdk');

const mnemonic = "gorilla fortune learn marble essay uphold defense hover index effort ice atom figure will improve mom indoor mansion people elder hill material donkey abandon gown";
const key = algosdk.mnemonicToSecretKey(mnemonic);
const firstRound = 7252500;

const txn = { 
    "to": key.addr,
    "fee": 10,
    "amount": 1234,
    "firstRound": firstRound,
    "lastRound": firstRound+1000,
    "genesisID": "testnet-v1.0",
    "genesisHash": "SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI="
};

const signedTxn = algosdk.signTransaction(txn, key.sk);

console.log(Buffer.from(signedTxn.blob).toString('base64'));

and the following Python script decodes the transaction and sends it:

import base64

import algosdk

# transaction bytes encoded in base64, as generated by the JS
tx_base64 = "gqNzaWfEQLtqNoYHwwuh9EHFK/VdVuagfZOhpCtaFuAxo+qSpJDun565bp6YP0rEBK/ev0jLOvPsLJlqHEwHiFAD7Dkl0QejdHhuiaNhbXTNBNKjZmVlzQl+omZ2zgBuqhSjZ2VurHRlc3RuZXQtdjEuMKJnaMQgSGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiKibHbOAG6t/KNyY3bEIEB21IF3WO/UrwIfJsmxdRKHHLZcS5p2IsP12fHJWI/Zo3NuZMQgQHbUgXdY79SvAh8mybF1EocctlxLmnYiw/XZ8clYj9mkdHlwZaNwYXk="

tx = algosdk.encoding.msgpack_decode(tx_base64)

algod_token = "your algod token"
algod_address = "http://localhost:8080"

acl = algosdk.algod.AlgodClient(algod_token, algod_address)

txid = acl.send_transaction(tx)

print("Transaction ID: {}".format(txid))

You will need to update the firstRound variable in the JS script to match the current round on TestNet, and then updated the variable tx_base64 in the Python script to be the output of the JS script.

3 Likes

Amazing! Everything’s working fine!
Thank you very much!

In which way I replace Buffer and require? Thanks. I wanna see a transaction with a php file that use a js script to find the transaction.

If your JS is executed inside the browser, remove completely the line const algosdk = require('algosdk'); and import algosdk as a script. See https://github.com/algorand/js-algorand-sdk#browser

For the buffer, I think you can replace it using btoa, but I have never tried. See https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/btoa

Thanks @fabrice for the code !
For others, here is the working JS code to convert a transaction signed with myAlgoWallet to base64 (to be sent to a Python backend for example) :

async function signTransaction(tx_base64) {
    const signed_tx = await myAlgoWallet.signTransaction(tx_base64);
    const signed_tx_base64 = btoa(String.fromCharCode.apply(null, signed_tx.blob));
    return signed_tx_base64
}
1 Like