[SOLVED] Sign and send transactions inside of a cloud function

My goal is to sign and send transactions inside of a cloud function to create a “gasless” “meta-transaction”. I am aware of the recommended ways to send meta-transactions but they are bulky and require additional 3rd party dependencies and service providers (as far as I know there really is no easy way).

Can I hardcode a wallets private and public key into some code like this. And then send that transaction to the blockchain instead of just returning it?

/(Found on Moralis forum at signedTransaction caller not owner in Cloud Function)/

Moralis.Cloud.define(“sign”, async (request) => {
const web3 = Moralis.web3ByChain(“0x13881”);
let signedTransaction = web3.eth.accounts.signTransaction(
{to: ‘0x96402b32bF48BfE2Fa74B7cB8ec59BB8A36cDa1d’, value: ‘1000000000’,gas: 2000000},
‘4324234234’);
return signedTransaction;
})

I believe that can be done, and btw if that is actually your private key I suggest you remove it from the post asap xd

edit: actually you might have to fully delete the post :sweat_smile:

Hopefully not a real private key. I didn’t even think of obscuring since it was in a different Moralis thread already :dizzy_face:. Next time I will be more careful and cut anything along those lines.

I think I need to change the structure of the call above. In case anyone else wants to know I think article is pretty close to what I want.

https://medium.com/finnovate-io/how-do-i-sign-transactions-with-web3-f90a853904a2

you some some example here:

I combined the Meduim article and the code on the Moralis documentation to get this, which worked. Thanks for the help!

//Cloud Server Code------------------
Moralis.Cloud.define(‘yourCloudFunctionNameHere’, async request => {
const _abi = [YOUR CONTRACT ABI];
const _contractAddress = ‘YOUR CONTRACT ADDRESS HERE’
const _gasAddress = ‘YOUR -GAS STATION WALLET- ADDRESS HERE’
const _private = ‘YOUR -GAS STATION WALLET- Private key here’

const web3 = Moralis.web3ByChain(‘0x89’) // Chain ID 0x89 is Matic Mainnet
const myContract = new web3.eth.Contract(_abi, _contractAddress)

//assign the parameters you will pass to this cloud function
let To = request.params.to;

const tx = {
//Gas station wallet to initiate transaction from
from: _gasAddress,
// Smart contract address with function you are trying to call
to: _contractAddress,
// Set gas to appropriate value, this worked for me…
gas: 963966,
//Payable value, likely not needed in a gas station function
value: 0,
// this encodes the ABI of the method and the arguements
// Change faucetFunction to whatever function you want to call, replace (To) with your
//parameters (To, From, Amount.
data: myContract.methods.faucetFunction(To).encodeABI()
}
const signPromise = web3.eth.accounts.signTransaction(tx, _private)

signPromise
.then(signedTx => {
// raw transaction string may be available in .raw or
// .rawTransaction depending on which signTransaction
// function was called
const sentTx = web3.eth.sendSignedTransaction(
signedTx.raw || signedTx.rawTransaction
)
sentTx.on(‘receipt’, receipt => {
return receipt
})
sentTx.on(‘error’, err => {
return err
})
})
.catch(err => {
return err
})
// THis returns the ‘receipt’ of the sent promise it included a transaction hash
return signPromise;
})

Client side code -----------------

Moralis.start({ serverUrl, appId });
let addressTo = ‘0x95ABA0f453457eE8Da7780d3d8’

const params = {
to: addressTo,
}

async function testCall(){
const _Result = await Moralis.Cloud.run(‘yourCloudFunctionNameHere’, params)
console.log(_Result)
}

Hello, I tried your code but i get the following error :

Error: {“message”:“Invalid JSON RPC response: “user not found””,“code”:141}

Here is my code :

const _contractAddress = "0xd0665Dfc6dF2c07C63Eeb6a51E6Cc4d030FD4700"; // controller testnet
  const _gasAddress = '0x599aE0C9bCCB202778022eFDd0eDa5ebC9EE8d69'
  const _private =config.get("controllerKey");

  const web3 = Moralis.web3ByChain('0x13881') // Chain ID 0x89 is Matic Mainnet
  const myContract = new web3.eth.Contract(_abi, _contractAddress)

  //assign the parameters you will pass to this cloud function
  // let To = request.params.to;
  const classNft = 0
  
  const tx = {
  //Gas station wallet to initiate transaction from
  from: _gasAddress,
  // Smart contract address with function you are trying to call
  to: _contractAddress,
  // Set gas to appropriate value, this worked for me…
  gas: 963966,
  //Payable value, likely not needed in a gas station function
  value: 0,
  // this encodes the ABI of the method and the arguements
  // Change faucetFunction to whatever function you want to call, replace (To) with your
  //parameters (To, From, Amount.
  data: myContract.methods.redeemGift(walletclaim,  classNft, code).encodeABI()
  }
  const signPromise = web3.eth.accounts.signTransaction(tx, _private)

  signPromise
  .then(signedTx => {
  // raw transaction string may be available in .raw or
  // .rawTransaction depending on which signTransaction
  // function was called
    const sentTx = web3.eth.sendSignedTransaction(
    signedTx.raw || signedTx.rawTransaction
    )
    sentTx.on('receipt', receipt => {
       return receipt
    })
    sentTx.on('error', err => {
       return err
    })
    })
  .catch(err => {
      return err
  })
    // THis returns the ‘receipt’ of the sent promise it included a transaction hash
  return signPromise;

Anyone has a lead ?

Thanks :slight_smile:

As usual, asking the question on a forum trigger the murphy law and make me find the answer ><

it worked if i define web3 like that :

const web3 = new Moralis.Web3(
    new Moralis.Web3.providers.HttpProvider(
      "https://matic-mumbai.chainstacklabs.com"
    )
  );
2 Likes