now it could be related to those approves
I thought so too. Probably because I was approving both transfers with the same Metamask wallet, when I shouldāve approved the wallet that stores our custom token somewhere else.
Did some digging & found out about web3ās signTransaction(), which can be used to automatically sign a transaction with apikey without the need to approve a transfer manually through Metamask.
So I created an api request that does that on the server side with nodejs.
...
const Web3 = require('web3');
const Accounts = require('web3-eth-accounts');
const Moralis = require('moralis/node');
...
require('dotenv').config();
const swapSmartCon = process.env.SWAP_SMART_CONTRACT;
const privateKey = process.env.TYS_PRIVATE_KEY;
router.post("/approve_tys_transfer", async (req, res) => {
if(parseInt(req.body.buyerAmt) <= 0) {
return false;
}
try {
const accounts = new Accounts(process.env.BSC_SPEEDY_NODE); // TESTNET
const buyerAmtStr = req.body.buyerAmt;
const buyerAmt = Web3.utils.toWei(buyerAmtStr.toString(), 'ether');
const params = {
to: swapSmartCon, // swap smart contract address
value: buyerAmt, // token value
gas: 2000000,
nonce: 0,
chainId: parseInt(process.env.BSC_CHAIN_ID) // bsc testnet chain id
};
const signed = await accounts.signTransaction(params, privateKey);
if(signed.hasOwnProperty("transactionHash")) {
const json = {
data: [signed.transactionHash],
success: true,
message: "Transaction approved."
}
res.json(json);
res.status(200);
return
}
console.log(signed);
} catch (error) {
console.log(error)
}
})
With the above API method I was able to get the data back, with rawTransaction, transactionHash, etcā¦
So what I did was:
- Have user to approve the transfer through the Metamask interface.
- Approve our wallet with the custom token by calling the API.
- Run the swap.
However, the transaction still failed but the error being thrown this time indicates that thereās not enough funds in our wallet.
Hereās the thing, thereās enough custom token in the wallet. My guess is that signTransaction() is signing the wrong token maybe?
While I was looking through the transaction, I also noticed that the inputs were empty & the params should be passed through the constructor & not through swap(). I searched through Moralisā documentation but couldnāt find anything that states how one could pass in smart contract constructor params with executeFunction().
const abi = await getSwapAbi();
const swapOpt = {
contractAddress: swapConAdd,
functionName: "swap",
abi: abi,
params: {
buyerToken: stableAdd,
buyer: buyerAdd,
buyerAmt: Moralis.Units.Token(buyerAmt.toString(), stableDec.toString()),
sellerAmt: Moralis.Units.Token(sellerAmt.toString(), "18")
}
};
const swap = await Moralis.executeFunction(swapOpt);
How do I pass in params as constructor parameters with Moralis.executeFunction(option)
?