Atomic Transfer Possible on API?

To perform atomic transfer, transactions are assigned a group id, then the signed transactions are pushed into an array. However, when I submit an array of signedTxns to algoexplorer API, I keep getting an error “msgpack decode error”

        let txns = [transaction1, transaction2];
        let txgroup = algosdk.assignGroupID(txns);
        let signedTx1 = transaction1.signTxn( myAccountA.sk )
        let signedTx2 = transaction2.signTxn( myAccountB.sk )
        let signed = [];
        signed.push( signedTx1 );
        signed.push( signedTx2 );
	let postUrl = "https://testnet.algoexplorerapi.io/v2/transactions";
        var reqOptions = {
	        method: "POST",
	        headers: {
	          "Content-Type": "application/x-binary",
	        },
	        body: signed
	 };
	 const txDetails = await (await fetch(postTransactionUrl, reqOptions)).json();

I believe putting signedTxn objects into an array messes with the formatting of it somehow. Is there no way to perform atomic transfers with an API?

You should use the algod client to send transactions, it takes care of things like marshalling to msgpack

1 Like

Thanks, unfortunately I keep getting a Bad Request response. I’m sending a simple asset creation txn which used to work when I just use the fetch syntax.

let txn = algosdk.makeAssetCreateTxnWithSuggestedParams(accountAddr, note, totalSupply, decimals, defaultFrozen, managerAddress, reserveAddress, freezeAddress, clawbackAddress, unitName, assetName, assetURL, "", getParams);
let signedTxn = txn.signTxn(thisAccount.sk);

const testServer = 'https://testnet.algoexplorerapi.io/';
const token = '';
const port = '';
let algodClientV2Test = new algosdk.Algodv2(token, testServer, port);
await algodClientV2Test.sendRawTransaction(signedTxn).do();

Am I missing something?

The code posted looks fine, there is usually an error message accompanying bad request like “tried to spend XXX” or something. That’d be helpful for debugging

1 Like

I’m still running into some trouble passing the binary data of transactions over https. Currently I’m trying to send several signed transactions (in the same group) through a POST Request to my backend server, where I sign off on one of them then submit to AlgoExplorer.

What’s the best way to do this? I’ve been experimenting with serializing them, which messes up the object format, and also multipart request, but to no avail.

Ah, I lied to you before, you should be passing an array of signed txn blobs.

Here is an example in my project:

Also myself and many other devs are in the Discord and happy to help with any questions :slight_smile:

Ok it’s all resolved. My solution for the next person struggling with sending transactions over http request. I used “js-base64” module. You have to convert the binary data to base64, send it via JSON, then convert it back on server side. For unsigned txn, you have to use algosdk.encodeUnsignedTransaction, then convert to base64.

// Client Side
let createAssetTxn = algosdk.makeAssetCreateTxnWithSuggestedParams(accountAddr, note, totalSupply, decimals, defaultFrozen, managerAddress, reserveAddress, freezeAddress, clawbackAddress, unitName, assetName, assetURL, "", params);
let dispenserTxn = algosdk.makePaymentTxnWithSuggestedParams(DISPENSER_PK, accountAddr, 250000, undefined, note, params); // fund address w min balance
let txns = [dispenserTxn, createAssetTxn];
let txgroup = algosdk.assignGroupID(txns);
let signedcreateAssetTxn = createAssetTxn.signTxn(thisAccount.sk);

// send the following JSON for req body
{
"dispenserTxnB64": Base64.fromUint8Array(algosdk.encodeUnsignedTransaction(dispenserTxn)),
"signedCreateAssetTxnB64": Base64.fromUint8Array(signedcreateAssetTxn)
})

// Server side
var dispenserTxn = algosdk.decodeUnsignedTransaction(Base64.toUint8Array(data.dispenserTxnB64));
var signedCreateAssetTxn = Base64.toUint8Array(data.signedCreateAssetTxnB64);
1 Like