[Ethereum] How execute a contract method with private key / sign send method

contract-invocationerc-20ethereum-wallet-dappethereumjsweb3js

I'd like to execute an erc20 contract method without unlocking a wallet, signing the transaction inside my code.
Here is how the code should look like:

  public async send(sender: string, receiver: string, value: number, key: string)
    : PromiEvent<object> {
    return this.contract.methods.transfer(receiver, value)
      .send({ from: sender });
  }

the current code doesn't allow me to sign manually, it assumes the sender address is unlocked. How can I sign send manually?

Best Answer

  public async send(sender: string, receiver: string, value: number, key: string)
    // @ts-ignore: PromiEvent extends Promise
    : PromiEvent<TransactionReceipt> {
    const query = this.contract.methods.transfer(receiver, value);
    const encodedABI = query.encodeABI();
    const signedTx = await this.web3.eth.accounts.signTransaction(
      {
        data: encodedABI,
        from: sender,
        gas: 2000000,
        to: this.contract.options.address,
      },
      key,
      false,
    );
    // @ts-ignore: property exists
    return this.web3.eth.sendSignedTransaction(signedTx.rawTransaction);
  }