[SOLVED] Send tokens from cloud function

Hi guys,
Iā€™d like to send tokens to my usersesā€™ addresses from backend, paying gas, so they wonā€™t see anything but the result
Iā€™ve written a Cloud function to do so, but it gives me errorā€¦
I donā€™t know if itā€™s the best way to do this, I accept any suggestion

Moralis.Cloud.define("transfer", async (request) => {

  const web3 = Moralis.web3ByChain("0x13881")	//mumbai testnet
  const contract = new web3.eth.Contract(CONTRACT_ABI, CONTRACT_ADDRESS);
  
  const address = request.param.address;
  const amount = request.param.amout;
  
  let data = await contract.methods.transfer(address, amount).encodeABI();
  let nGas = web3.utils.toHex(100000);

  let txObj = {
    "gas": nGas,
    "to": USER_ADDRESS,
    "value": 0x0,
    "data": data,
    "from": CONTRACT_OWNER
  }
  
  await web3.eth.accounts.signTransaction(txObj, PRIVATE_KEY, function(err, signedTx) {
    if (err)
      return {"KO", err}
    else
    {
      await web3.eth.sendSignedTransaction(signedTx.rawTransaction, function(err, res) {
        if (err)
          return {"KO", err}
        else{
		  return {"OK", res}          
        }
      });
    }
  });

}

This is the error in dashboard log

2022-06-09T09:05:56.067Z - Error: Invalid function: "transfer"
    at handleCloudFunction (/moralis-server/lib/Routers/FunctionsRouter.js:201:13)
    at /moralis-server/lib/PromiseRouter.js:85:20
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
2022-06-09T09:00:36.590Z - SyntaxError: Unexpected identifier
    at customUserPlugin (/moralis-server/cloud/main.js:157:26)
    at /moralis-server/lib/cloud-code/plugins/index.js:144:15
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async Object.initialize (/moralis-server/lib/cloud-code/plugins/index.js:133:3)

There are some syntax errors in the cloud code. You can check the code for syntax errors in any js console and then try again.

following it. I also have to do a similar thing but I am very new to JS.
@johnversus @Joe_Doe how can I call my cloud function from the corn job. I am very confused about it. For example, if I have to do the same, to send tokens to my users from the backend every month so it must be scheduled as ā€˜Jobā€™ on moralis server but how can I call a cloud function from the Job. If you know this please help me

you can set a cloud function as a job directly, or call any other function defined in cloud code from a job

1 Like

SyntaxError found, it was the return objectā€¦{ result: ā€œKOā€, msg: err }

The other error is still there

2022-06-09T12:49:49.103Z - Error: Invalid function: "transfer"
    at handleCloudFunction (/moralis-server/lib/Routers/FunctionsRouter.js:201:13)
    at /moralis-server/lib/PromiseRouter.js:85:20
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

This is my JavaScript call

const params = {
		address: ADDRESS_TO,
		amount: 10
	}

console.log(await Moralis.Cloud.run("transfer", params));

Did you fix this one?

I tried to run in browser console, it gave me this error.

from this line

And also a bracket ) at end of the code is missing.

I guess fixing these should solve the invalid function error.

Now, fixed some errors, edit a bit my function, but the result is the same

Moralis.Cloud.define("transfer", async (request) => {

  const ABI =abi;
  const CONTRACT_ADDRESS = address;
  const CONTRACT_OWNER = owner;
  const PRIVATE_KEY = private_key;
  
  const web3 = Moralis.web3ByChain("0x13881")	//mumbai testnet
  const contract = new web3.eth.Contract(ABI, CONTRACT_ADDRESS);
  
  const address = request.params.address;
  const amount = request.params.amount;
  
  let data = await contract.methods.transfer(address, amount).encodeABI();
  let nGas = web3.utils.toHex(100000);

  let txObj = {
    "gas": nGas,
    "to": CONTRACT_ADDRESS,
    "value": 0x0,
    "data": data,
    "from": CONTRACT_OWNER
  }
  
  await web3.eth.accounts.signTransaction(txObj, PRIVATE_KEY, function(err, signedTx) {
    if (err)
      return {
			result: "KO",
			msg: err
		}
    else
    {
       web3.eth.sendSignedTransaction(signedTx.rawTransaction, function(err, res) {
        if (err)
          return {
				result: "KO",
				msg: err
			}
        else{
		  return {
				result: "OK",
				msg: res
			}                  
        }
      });
    }
  });
});

Error

Error: Invalid function: "transfer"
    at handleCloudFunction (/moralis-server/lib/Routers/FunctionsRouter.js:201:13)
    at /moralis-server/lib/PromiseRouter.js:85:20
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

Did you fix all this variables ??
If not, try fix them all

yes, in my code Iā€™ve the real data, here to be shorter Iā€™ve just written those names

What about making this value: "0x00"

Just edited the value in 0x00.
It gives no error in dashboard logs, but I get these two messages

2022-06-09T15:12:33.659Z - Ran cloud function transfer for user undefined with:
  Input: {"address":"0x8eDc8d607931a870392FF61fDaa6F4001d0cF97c","amount":10}
  Result: undefined
2022-06-09T15:12:33.578Z - Ran cloud function getPluginSpecs for user undefined with:
  Input: {}
  Result: [{"name":"coreservices","functions":["getConfig","setConfig","getWeb3ApiToken","track","getOrganization","setOrganization","getEventSyncs","addEventSync","removeEventSync","listEventSyncStatus","getAddressSyncs","addAddressSync","removeAddressSync","listAddressSyncStatus","getProviders","setChains","getChains"]}]

You can verify the transfer on the explorer if it went through

I had to delete the ā€œawaitā€ instruction before the web3.eth.accounts.signTransaction call to make is works!
I can see the transaction on the explorer, but I get always ā€œundefinedā€ as result in my JavaScript call
Iā€™ve tried changing the code, but everytime I touch something it gives me tons of errors, CORS etcā€¦
If anyone knows how to get a valid response Iā€™ll appreciate, otherwise Iā€™ll go on this way

Anyway thank you all for your support

You can replace this with this

    let signedTransaction = await web3.eth.accounts.signTransaction(
      txObj,
      privateKey
    );

    logger.info(signedTransaction);

    const sentTx = await web3.eth.sendSignedTransaction(
      signedTransaction.raw || signedTransaction.rawTransaction
    );

    logger.info(sentTx);

    logger.info("Transaction Hash", sentTx.transactionHash);
    return { status: true, sentTx };

Where const logger = Moralis.Cloud.getLogger();

@qudusayo, it works!!!
I donā€™t know how to thank you

This is my entire function, in case could be of any help to someone else

Moralis.Cloud.define("transfer", async (request) => {
  
  const ABI = contract_abi;
  const CONTRACT_ADDRESS = contract_address;
  const CONTRACT_OWNER = contract_owner;
  const PRIVATE_KEY = private_key;
  
  //const logger = Moralis.Cloud.getLogger();
  
  const web3 = Moralis.web3ByChain("0x13881")	//mumbai testnet
  const contract = new web3.eth.Contract(ABI, CONTRACT_ADDRESS);
  
  const address = request.params.address;
  const amount = request.params.amount;
  
  let data = contract.methods.transfer(address, amount).encodeABI();
  let nGas = web3.utils.toHex(100000);

  let txObj = {
    "gas": nGas,
    "to": CONTRACT_ADDRESS,
    "value": 0x00,
    "data": data,
    "from": CONTRACT_OWNER
  }
  
  let signedTx;
  try {
  	signedTx = await web3.eth.accounts.signTransaction(txObj, PRIVATE_KEY);
  } catch(err) {
    return {
      result: "KO",
      msg: err
    };
  }
  
  //logger.info(signedTx);
  
  let sentTx;
  try {
    sentTx = await web3.eth.sendSignedTransaction(
      signedTx.rawTransaction  || signedTx.raw);
  } catch(err) {	  
    return {
      result: "KO",
      msg: err
    };
  }
  
  //logger.info(sentTx);
  //logger.info("Transaction Hash", sentTx.transactionHash);
  
  return {
    result: "OK",
    msg: sentTx.transactionHash
  };

  });

2 Likes