Send transaction created using python sdk to algosigner?

Hi I am developing project where there are multiple transactions throughout the project one of which is creation of contract for which I have created transaction as follows using python sdk

txn = transaction.ApplicationCreateTxn(
        sender=platform_algo_account,
        on_complete=transaction.OnComplete.NoOpOC,
        approval_program=approval,
        clear_program=clear,
        global_schema=globalSchema,
        local_schema=localSchema,
        app_args=app_args,
        sp=client.suggested_params(),
    )
return txn

catching txn in my api as follows and while returning it to pass to front-end so that I can use Algosigner sign and send functionality It gives me error

Error: TypeError: Object of type 'ApplicationCreateTxn' is not JSON serializable

Following is API call using falsk python.

txn = contract_creation.create_proposal(proposal_id,proposal_creator,platform_algo_account,platform_algo_private_key,proposal_type,proposal_details,proposal_amount,proposal_start_time,proposal_end_time,yes_count,no_count)

    print("Type of TXN---------------------------------------------",type(txn))
    return json.dumps({ 'txn' : txn})

Onchecking txn type: <class ‘algosdk.future.transaction.ApplicationCreateTxn’>

Please guide for best practice.

It would be best if you used JS SDK to build transactions.
Using python SDK you need to send that transaction to frontend and you will have serialization issues.

okay. Thank you ill try that

Hi,
I am able to create ApplicationCreateTxn using Pythonsdk and Sign and Send the transaction using algosigner. But in response I am only getting txn. I also need App ID for further actions on application. How do I get that?

Applications don’t have an ID until they’re sent to the network.

You can use the txId to make an Indexer call and find the created-application-index

In JavaScript it would look like this:

let sentTxn = await indexer.lookupTransactionByID(txId).do();
let appId = sentTxn['created-application-index'];
2 Likes

I am already sending the transaction
AlgoSigner.send({ ledger: 'TestNet', tx: signedTxs[0].blob, })
Also able to view Application ID and transaction on testnet explorer. But algosigner is not returning application ID
Do I need to send it using sdk ?

No, how you send it is irrelevant.

You need to get the transaction back from the network in order to get it’s AppID. Just as you searched for the ID on the explorer, you need to do the same but from your code.

That can be done with a call to Indexer like I mentioned; I also think you can use Algod to call the pending transactions endpoint after the tx is sent and you’re waiting for confirmation.

1 Like

Thank you for your guidance.
I tried as you suggested

AlgoSigner.send({
            ledger: 'TestNet',
            tx: signedTxs[0].blob,
          })
          .then((r)=>{
            console.log("Response: ",r)
            let sentTxn = AlgoSigner.indexer({
              ledger: 'TestNet',
              path: '/v2/transactions/r.txID',
            })
          })

But giving me error as:

message: "invalid input: unable to parse base32 digest data 'txid': illegal base32 data at input byte 0"}

It looks like you’re not using the interpolated value of txID inside the string and rather using the literal ‘r.txid’ string.

This should do it :slight_smile:

path: '/v2/transactions/' + r.txID

As per your response tried following:

let sentTxn = AlgoSigner.indexer({
              ledger: 'TestNet',
              path: '/v2/transactions/' + r.txID,
            })
            .then((sentTxn)=>{
              // let appId = sentTxn['created-application-index'];
               console.log("Responsesss: ",sentTxn)
            })
          })

Still getting error:

"invalid input: unable to parse base32 digest data 'txid': illegal base32 data at input byte 0"

Can you print the object r and r.txID just before calling AlgoSigner.indexer
(using console.log) and show it to us?

Thank you once again I am able to hit indexer api, but it is giving me error:

'no transaction found for transaction id: 7ARPM47EDLV6OIEV5XJRUMYKH2M5KGZDTVJEX5UZBF7P5OB3FI6Q'}

Where as if I check on explorer I am able view the transaction.

Thank you for your guidance I am able get the appId full code as below:

async function waitForAlgosignerConfirmation(tx) {
  console.log(`Transaction ${tx.txId} waiting for confirmation...`);
  let status = await AlgoSigner.algod({
    ledger: 'TestNet',
    path: '/v2/transactions/pending/' + tx.txId
  });

  while(true) {
    if(status['confirmed-round'] !== null && status['confirmed-round'] > 0) {
      //Got the completed Transaction
      console.log(`Transaction confirmed in round ${status['confirmed-round']}.`);
      break;
    }

    status = await AlgoSigner.algod({
      ledger: 'TestNet',
      path: '/v2/transactions/pending/' + tx.txId
    });
  }
  
  return tx;
}

const response = await fetch(process.env.REACT_APP_PORT+'/addproposal', post)
      await fetch(process.env.REACT_APP_PORT+'/addproposal', post)
      .then(response => response.json())
      .then((data) => {
        let trans = data.transaction
        console.log("Trans: ",trans)
        const recovered_pay_txn = algosdk.decodeUnsignedTransaction(Buffer.from(trans.toString(), "base64"))
        let base64Tx = AlgoSigner.encoding.msgpackToBase64(recovered_pay_txn.toByte())
        
        let signedTxs =  AlgoSigner.signTxn([{txn: base64Tx}])
        .then((signedTxs)=>{
          console.log("Test",signedTxs)
          AlgoSigner.send({
            ledger: 'TestNet',
            tx: signedTxs[0].blob,
          })
         .then((tx) => waitForAlgosignerConfirmation(tx)) // see algosignerutils.js
          .then((tx) => {
                  console.log("waiting:",tx)
                  let sentTxn = AlgoSigner.indexer({
                            ledger: 'TestNet',
                            path: '/v2/transactions/' + tx.txId,
                          })
                          .then((sentTxn)=>{
                            console.log("Responsesss: ",sentTxn)
                            let appId = sentTxn.transaction['created-application-index'];
                            console.log("Responsesss: ",appId)
                          })
              }
      
          )
         
        })  
        
      })
1 Like

Hi
How did you serialze the ApplicationCreateTxn and sent it to frontend please?
I appreciate your help
I also have this “TypeError: Object of type ‘ApplicationCreateTxn’ is not JSON serializable”
error

Welcome to Algorand!

The best solution is always to msgpack serialize transactions between frontend and backend.
If the transfer is to be taken in text format, you should in addition base64 the result.
See Encoding and Decoding - Algorand Developer Portal for details

1 Like