Hey guys,
I am trying to do a bit of a fancy atomic transfer.
Basically I want two transactions to be signed in the browser, and 2 transactions to be signed in the backend. And I want those 4 transactions to be atomic.
Reason is that I want a person to be able to sign the first transactions through the browser and a wallet plugin directly, without getting the private key in my own backend.
And sign the two others with the app secret key, so absolutely not in the browser.
So what I do is that, I create both first transactions in the frontend, I group them, save the group generated, and signed them.
const optInTxn = algosdk.makeAssetTransferTxnWithSuggestedParams(
buyerAddress,
buyerAddress,
undefined,
undefined,
0,
new Uint8Array(0),
assetId,
params
)
const algoFill = algosdk.makePaymentTxnWithSuggestedParams(
buyerAddress,
escrowAccount,
price * 1000000,
undefined,
new Uint8Array(0),
params
)
algosdk.assignGroupID([algoFill, optInTxn])
const signedTxn = await myAlgoWallet.signTransaction([
optInTxn.toByte(),
algoFill.toByte(),
])
Then I pass the blob I get from signedTxn[0] and signedTxn[1] to the backend.
I pass the group I get from algoFill.group to the backend too.
And the params by the way, since I need the same for all (kinda).
Then in the backend, I do
const appArgs = []
appArgs.push(new Uint8Array(Buffer.from('buy')))
const callTxn = algosdk.makeApplicationNoOpTxn(
PLATEFORM_ADDR,
params,
appId,
appArgs
)
const assetTransfer = algosdk.makeAssetTransferTxnWithSuggestedParams(
escrowAccount,
buyerAddress,
undefined,
undefined,
1,
new Uint8Array(0),
assetId,
params
)
callTxn.group = new Buffer.from(group)
assetTransfer.group = new Buffer.from(group)
const signedCall = callTxn.signTxn(plateformSK)
const lsig = new algosdk.LogicSigAccount(
new Uint8Array(Buffer.from(escrowSign, 'base64'))
)
const signedAsset = algosdk.signLogicSigTransaction(assetTransfer, lsig)
const signed = [
signedCall,
new Uint8Array(algoFillSigned),
new Uint8Array(optInSigned),
signedAsset.blob,
]
const createTxId = await algodClient.sendRawTransaction(signed).do()
await waitTransaction(createTxId.txId, 2)
And then the error I get :
'{"message":"TransactionPool.Remember: transactionGroup: incomplete group: KUGOVUOHYQTCWJKPKDTNZKBXALNVGT5OXPLNMNU3KE3S4LIGRCHQ != KPXWCVII4W7ROXS2UV4H4NMRMYJ5GSCUIJRA3F6PK74LLICHHARQ ({{} [E2JSYIOCTVYK67K7AANTHILFLIHJN6ZHDSLH627RHT2PEAW5LMXA 43KMZ5L46DN6LV6V7SGYU54CS5KWXWNYHKYLKNC7AAVXSSNJ3WOQ]})"}\n'
For infos, I am passing those data as HTTPS POST.
I tried nearly EVERYTHING. And so if I group only the 2 backend ones, it works. If I group only the two front ones it work. So then I tried to assignGroupId from the browser for the 4, and signed the 2 missing signature in the backend, couldn’t make it work.
And when I do the 4 in the backend or the 4 in the browser it works too.
So what can I do ? What am I doing it wrong ?
Or maybe there is a better way to achieve what I want ?
Thanks you very much for the help guys.
Cheers