Zum Hauptinhalt springen

Axios: How to send an EIP-1559 raw transaction in js

In general the Javascript libraries like Ethers.js or web3.js have build in methods to sign and send a raw transaction but there might be situations where you’d want interact with the Ethereum API via plain json-rpc requests.

We’ll be using Axios to send the raw transaction but before that we’ll need to also craft the transaction object, sign it with the private key and serialize it, @ethereumjs/tx is a pretty good library that does the job.

Prerequisites:

  • Install Axios: npm i axios

  • Install @ethereumjs/tx: npm install @ethereumjs/tx

Here’s how the working code would look like (make sure to replace the Infura API KEY, private key and from, to addresses placeholders):

const axios = require("axios");
const Common = require("@ethereumjs/common").default;
const { FeeMarketEIP1559Transaction } = require("@ethereumjs/tx");

const infuraUrl = "https://ropsten.infura.io/v3/<API_KEY>";

const payloadProto = {
jsonrpc: "2.0",
method: "",
params: [],
id: 1,
};

(async () => {
const addressFrom = "0x...";
// Exclude 0x at the beginning of the private key
const privKey = Buffer.from("....", "hex");
const addressTo = "0x...";
const valueInEther = "0x16345785D8A0000"; // 0.1 ETH = 100000000000000000 Wei

// Get the address transaction count in order to specify the correct nonce
const payloadCount = Object.assign({}, payloadProto, {
method: "eth_getTransactionCount",
params: [addressFrom, "latest"],
});
var resp = await axios({
url: infuraUrl,
method: "POST",
data: payloadCount,
headers: { "Content-Type": "application/json" },
});
const txnCount = resp.data.result;

// Estimate the tx gas limit
const payloadLimit = Object.assign({}, payloadProto, {
method: "eth_estimateGas",
params: [{ from: addressFrom, to: addressTo, value: valueInEther }],
});
resp = await axios({
url: infuraUrl,
method: "POST",
data: payloadLimit,
headers: { "Content-Type": "application/json" },
});
const limit = resp.data.result;

// Create the EIP-1559 transaction object
var txObject = {
nonce: txnCount,
gasLimit: limit,
to: addressTo,
value: valueInEther,
maxFeePerGas: "0x2E90EDD000", // 200000000000 Wei
maxPriorityFeePerGas: "0x77359400", // 2000000000 Wei
chainId: 3,
type: 0x2,
};

// Sign the transaction with the private key
var chain = new Common({ chain: "ropsten", hardfork: "london" });
const tx = FeeMarketEIP1559Transaction.fromTxData(txObject, { chain });
const signedTransaction = tx.sign(privKey);

//Convert to raw transaction string
var serializedTx = signedTransaction.serialize();
var rawTxHex = "0x" + serializedTx.toString("hex");

// log raw transaction data to the console in case you need it for troubleshooting
console.log("Raw transaction data: " + rawTxHex);

// Send the raw transaction
const payloadTx = Object.assign({}, payloadProto, {
method: "eth_sendRawTransaction",
params: [rawTxHex],
});
resp = await axios({
url: infuraUrl,
method: "POST",
data: payloadTx,
headers: { "Content-Type": "application/json" },
});
const txhash = resp.data;
console.log(txhash);
})();