How to setup your DAPPs to not use “MetaMask” plugin but sign the transaction backend.

How to setup your DAPPs to not use “MetaMask” plugin but sign the transaction backend.

I have recently launched Decentralised Applications(DAPPS) in production. Though it was fun but challenging ride, the knowledge accumulated was very good. Since developing the reactjs application from scratch and getting it ready for production is something I felt very cumbersome process.

We are in the Web 3.0 era, yes everything is getting decentralised, we are going back to basics but with wonderful technology (BLOCKCHAIN) to have immutability, transparency in transactions. Having said that, adopting to DAPPS is not that easy since it requires few plugin’s to enable to perform the transactions. So many DAPPs are out there with an extension(plugin) to enable in order to use it for day to day operations. But why ?

Why end users must worry about those plugin’s?, all they want is to use the services & get / make the payment isn’t it?

When we are developing DAPPs, most important thing as a developers to keep in mind is “end user”, at the end of the day without users traction even if you build super great applications it will be just a scrap!

In this article, I will explain how to build your DAPPs to use the content provider & sign the transactions under the hood. So from user standpoint, it would be like normal application but they actually dealing with decentralised apps.

Credit goes to this developer : Click here


  1. Node(peer) that is running ethereum blockchain. You can setup your own, or use it for FREE from Infura. it’s open source & absolutely free. All you need is to setup a project and get the API key for the respective network(testnet / mainnet).
  2. Web3
  3. ethereumjs-tx
const Web3 = require('web3');
const EthereumTx = require('ethereumjs-tx')
const infura = `${process.env.INFURA_API_KEY}`;
const web3 = new Web3(new Web3.providers.HttpProvider(infura));
web3.eth.defaultAccount = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
var abi = process.env.ABI;
var pk = process.env.PRIVATEKEY; // private key of your account
var toadd = process.env.WALLET_DESTINATION;
var address = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; //Contract Address
web3.eth.getTransactionCount(web3.eth.defaultAccount, function (err, nonce) {
console.log(“nonce value is “, nonce);
const contract = new web3.eth.Contract(JSON.parse(abi), address, {from: web3.eth.defaultAccount ,gas: 3000000,}
const functionAbi = contract.methods.mymethodname(args).encodeABI();

Here -> args represent number of argument which methods requires.. so if you have more than one argument, then separate that by “comma”

mymethodname -> represent your method name in smart contract

var details = {"nonce": nonce,"gasPrice": web3.utils.toHex(web3.utils.toWei('47', 'gwei')),"gas": 300000,"to": address,"value": 0,"data": functionAbi,};

Here, ‘47’ is gas price. I recommend you to pull it from gas station, so that it is automatic & set the price as of that date.

“to” -> you can set it as contract address or “other wallet account”.

“gas” -> gasLimit, you can again set it to pull using “estimateGas” method. for now, it’s hardcoded

const transaction = new EthereumTx(details);
transaction.sign(Buffer.from(pk, ‘hex’))
var rawdata = ‘0x’ + transaction.serialize().toString(‘hex’);
web3.eth.sendSignedTransaction(raw).on(‘transactionHash’, function(hash){    console.log([‘transferToStaging Trx Hash:’ + hash]);}).on(‘receipt’, function(receipt){    console.log([‘transferToStaging Receipt:’, receipt]);}).on(‘error’, console.error);

Now, you are good to call your transaction without calling metamask!, it’s all running under the hoods. User now not required to install / setup Metamask plugin.

Note: this examples works when user want to just use the services offered and the transactions are being signed by just one account which uses sender’s private key.

If you want to sign every transaction with respective users private key, then it’s different ballgame.

Check below the complete code

instantiateContract = (args) =>{const infura = `${process.env.INFURA_API_KEY}`;const web3 = new Web3(new Web3.providers.HttpProvider(infura));web3.eth.defaultAccount = process.env.ACCOUNT_ADDRESS;var abi = process.env.ABI;var pk  = process.env.PRIVATEKEY;  // private key of your accountvar toadd = process.env.WALLET_DESTINATION;var address = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; //Contract Addressweb3.eth.getTransactionCount(web3.eth.defaultAccount, function (err, nonce) {console.log(“nonce value is “, nonce);const contract = new web3.eth.Contract(JSON.parse(abi), address, {from: web3.eth.defaultAccount ,gas: 3000000,})const functionAbi = contract.methods.mymethodname(args).encodeABI();var details = {“nonce”: nonce,“gasPrice”: web3.utils.toHex(web3.utils.toWei('47', ‘gwei’)),“gas”: 300000,“to”: address,“value”: 0,“data”: functionAbi,};const transaction = new EthereumTx(details);transaction.sign(Buffer.from(pk, ‘hex’) )var rawData = ‘0x’ + transaction.serialize().toString(‘hex’);web3.eth.sendSignedTransaction(rawData).on(‘transactionHash’, function(hash){console.log([‘transferToStaging Trx Hash:’ + hash]);}).on(‘receipt’, function(receipt){console.log([‘transferToStaging Receipt:’, receipt]);}).on(‘error’, console.error);});}

Note : Like this article?, give Logeswaran a thumbs-up(Claps) & follow him on Linkedin / Twitter

If you have followed any other way to get the DAPPs more user friendly, please comment below..

Reach me out if you need any help in setting up this successfully.

*** Very very careful, while you are exposing the private key *** - It is not recommended to expose yoru private key in code, so please find best approach to pass it on.

What's Your Reaction?