How to sign a transaction without sending it somewhere in Metamask

2.6k Views Asked by At

I'm trying to make a signed transaction in Android metamask using wallet connect send the transaction to my backend-server and then submit it to blockchain.

However, it's hard to find how I can just sign transaction(not sending it) and send it to my backend server.

I can signed the message using personal_sign, but not getting how to sign a transaction.

1

There are 1 best solutions below

1
On

Why do you want to submit the transaction to the backend without executing it? Wouldn't it just be easier to execute the transaction immediately?

Anyways, Metamask doesn't support the RPC for only signing transactions without submitting them. See https://github.com/MetaMask/metamask-extension/issues/3475

EDIT: to send a transaction and send it, just use the following code, modified from my answer at https://stackoverflow.com/a/71941911/11628256:

// The ABI tells ethers.js or web3.js how to interact with a type of contract - the following is a generic EIP-20 ABI I found
let abi = [{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}];
// Your NFT contract's address
let contractAddress = "0xPUTYOURCONTRACTADDRESSHERE";

// Information for the transfer
let myAccount = "0xPUTYOURADDRESSHERE"
let amountToTransfer = 1234;

// The following setup is taken from https://docs.ethers.io/v5/getting-started/#getting-started--connecting

// A Web3Provider wraps a standard Web3 provider, which is
// what MetaMask injects as window.ethereum into each page
const provider = new ethers.providers.Web3Provider(window.ethereum);

// MetaMask requires requesting permission to connect users accounts
let accounts = await provider.send("eth_requestAccounts", []);
let account = accounts[0];

// The MetaMask plugin also allows signing transactions to
// send ether and pay to change state within the blockchain.
// For this, you need the account signer...
const signer = provider.getSigner();

// This code tells ethers.js how to interact with your token contract
const tokenContractReadonly = new ethers.Contract(contractAddress, abi, provider);
// Connecting with a signer allows you to use all the methods of the contract
const tokenContract = tokenContractReadonly.connect(signer);

// Transfer
tokenContract.transfer(myAccount, Math.pow(10, await tokenContract.decimals()) * amountToTransfer);