I am getting this error when trying to transfer asset from owners account to buyers account. Can somebody help me here to find what I am doing wrong here:
Received status 400: TransactionPool.Remember: transaction V4XP55JZWMIM4LVMJIHS2K3VI5EMB3QS62KKFMFTEASBFBYBYQNQ: logic eval error: receiver error: must optin, asset 145047366 missing from 33H5EMCRX7HV2BQOCW55KNQRW7U5GUTAD4XIDVJ67NSLMRFRHVK4EHXB5Q. Details: pc=760, opcodes=global MinTxnFee
itxn_field Fee
itxn_submit
Here is my react code:
const executeTransfer = async () => {
const nftID = 145047366;
const params = await algodClient.getTransactionParams().do();
params.fee = 1000;
params.flatFee = true;
const enc = new TextEncoder();
const note = enc.encode("executeTransfer");
const app_args = [
note
]
const execute = await algosdk.makeApplicationCallTxnFromObject({
appIndex: 145047401,
from: "33H5EMCRX7HV2BQOCW55KNQRW7U5GUTAD4XIDVJ67NSLMRFRHVK4EHXB5Q",
foreignAssets: [nftID],
onComplete: OnApplicationComplete.NoOpOC,
suggestedParams: params,
appArgs: app_args,
accounts: ["OHNE3VQKVMYW5ICE275OGOB3WXWSL7QDEYQBDNP5A3U2WSIFI6A3AY4YUI", "OHNE3VQKVMYW5ICE275OGOB3WXWSL7QDEYQBDNP5A3U2WSIFI6A3AY4YUI"]
})
console.log("execute", execute)
algosdk.assignGroupID([execute])
const signedTxn = await myAlgoConnect.signTransaction(execute.toByte());
let groupedSignedTxns = []
groupedSignedTxns.push(signedTxn.blob)
const response = (await algodClient.sendRawTransaction(groupedSignedTxns).do());
console.log("response", response)
}
And here is my pyteal code for execute transfer function:
royaltyFee = App.globalGet(Constants.royaltyFee)
collectedFees = App.globalGet(Constants.collectedFees)
feesToBePaid = ScratchVar(TealType.uint64)
executeTransfer = Seq([
Assert(Gtxn[0].application_args.length() == Int(1)), # Check that there is only 1 argument
Assert(Global.group_size() == Int(1)), # Check that is only 1 transaction
defaultTransactionChecks(Int(0)), # Perform default transaction checks
Assert(App.localGet(seller, Constants.approveTransfer) == Int(1)), # Check that approval is set to 1 from seller' side
Assert(Or(
And(seller != buyer,
App.localGet(buyer, Constants.approveTransfer) == Int(1)), # Check approval from buyer' side
Global.round() > App.globalGet(Constants.waitingTime) # Alternatively, the seller can force the transaction if enough
+ App.localGet(seller, Constants.roundSaleBegan))), # time has passed
Assert(serviceCost < amountToBePaid), # Check underflow
checkNFTBalance(seller, App.globalGet(Constants.AssetId)), # Check that the seller owns the NFT
feesToBePaid.store( # Reduce number of subroutine calls by saving the variable inside a scratchvar variable
If(seller == App.globalGet(Constants.Creator)).Then(Int(0)) # Compute royalty fees: if the seller is the creator, the fees are 0
.Else(computeRoyaltyFee(amountToBePaid - serviceCost, royaltyFee))),
Assert(Int(2 ** 64 - 1) - feesToBePaid.load() >= amountToBePaid - serviceCost), # Check overflow on payment
Assert(Int(2 ** 64 - 1) - collectedFees >= feesToBePaid.load()), # Check overflow on collected fees
Assert(amountToBePaid - serviceCost > feesToBePaid.load()),
transferAsset(seller, # Transfer asset
Gtxn[0].sender(),
App.globalGet(Constants.AssetId)),
sendPayment(App.globalGet(Constants.royalty_addr), feesToBePaid.load()), # Pay seller
closeAccountTo(seller),
App.globalPut(Constants.collectedFees, collectedFees + feesToBePaid.load()), # Collect fees
App.localDel(seller, Constants.amountPayment), # Delete local variables
App.localDel(seller, Constants.approveTransfer),
App.localDel(buyer, Constants.approveTransfer),
Approve()
])