diff --git a/src/App.jsx b/src/App.jsx
index 2d73f48..94af4f6 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -2,7 +2,8 @@ import { useEffect, useState } from 'react';
import { NearContext } from './context';
import { Wallet } from './services/near-wallet';
import Navbar from './components/Navbar';
-import { EthereumView } from './components/Ethereum/Ethereum';
+import { EthereumView } from './components/EVM/Ethereum';
+import { BaseView } from './components/EVM/Base';
import { BitcoinView } from './components/Bitcoin';
import { MPC_CONTRACT } from './services/kdf/mpc';
@@ -68,6 +69,7 @@ function App() {
onChange={(e) => setChain(e.target.value)}
>
+
@@ -75,6 +77,9 @@ function App() {
{chain === 'eth' && (
)}
+ {chain === 'base' && (
+
+ )}
{chain === 'btc' && (
)}
diff --git a/src/components/EVM/Base.jsx b/src/components/EVM/Base.jsx
new file mode 100644
index 0000000..598858b
--- /dev/null
+++ b/src/components/EVM/Base.jsx
@@ -0,0 +1,325 @@
+import { useState, useEffect, useContext, useRef } from "react";
+import PropTypes from "prop-types";
+
+import { NearContext } from "../../context";
+import { useDebounce } from "../../hooks/debounce";
+import { getTransactionHashes } from "../../services/utils";
+import { TransferForm } from "./Transfer";
+import { FunctionCallForm } from "./FunctionCall";
+import { EthereumVM } from "../../services/evm";
+
+const Evm = new EthereumVM("https://base-sepolia.drpc.org");
+
+const contractAddress = "0xCd3b988b216790C598d9AB85Eee189e446CE526D";
+
+const transactions = getTransactionHashes();
+
+export function BaseView({ props: { setStatus, MPC_CONTRACT } }) {
+ const { wallet, signedAccountId } = useContext(NearContext);
+
+ const [loading, setLoading] = useState(false);
+ const [step, setStep] = useState(transactions ? "relay" : "request");
+ const [signedTransaction, setSignedTransaction] = useState(null);
+ const [senderLabel, setSenderLabel] = useState("");
+ const [senderAddress, setSenderAddress] = useState("");
+ const [balance, setBalance] = useState(""); // Add balance state
+ const [action, setAction] = useState("transfer");
+ const [derivation, setDerivation] = useState(
+ sessionStorage.getItem("derivation") || "ethereum-1"
+ );
+ const [reloaded, setReloaded] = useState(transactions.length);
+
+ const [gasPriceInGwei, setGasPriceInGwei] = useState("");
+ const [txCost, setTxCost] = useState("");
+
+ const derivationPath = useDebounce(derivation, 1200);
+ const childRef = useRef();
+
+ useEffect(() => {
+ async function fetchEthereumGasPrice() {
+ try {
+ // Fetch gas price in Wei
+ const gasPriceInWei = await Evm.web3.eth.getGasPrice();
+
+ // Convert gas price from Wei to Gwei
+ const gasPriceInGwei = Evm.web3.utils.fromWei(gasPriceInWei, "gwei");
+
+ // Gas limit for a standard ETH transfer
+ const gasLimit = 21000;
+
+ // Calculate transaction cost in ETH (gwei * gasLimit) / 1e9
+ const txCost = (gasPriceInGwei * gasLimit) / 1000000000;
+
+ // Format both gas price and transaction cost to 7 decimal places
+ const formattedGasPriceInGwei = parseFloat(gasPriceInGwei).toFixed(7);
+ const formattedTxCost = parseFloat(txCost).toFixed(7);
+
+ console.log(
+ `Current Sepolia Gas Price: ${formattedGasPriceInGwei} Gwei`
+ );
+ console.log(`Estimated Transaction Cost: ${formattedTxCost} ETH`);
+
+ setTxCost(formattedTxCost);
+ setGasPriceInGwei(formattedGasPriceInGwei);
+ } catch (error) {
+ console.error("Error fetching gas price:", error);
+ }
+ }
+
+ fetchEthereumGasPrice();
+ }, []);
+
+ // Handle signing transaction when the page is reloaded and senderAddress is set
+ useEffect(() => {
+ if (reloaded && senderAddress) {
+ signTransaction();
+ }
+
+ async function signTransaction() {
+ const { big_r, s, recovery_id } = await wallet.getTransactionResult(
+ transactions[0]
+ );
+ const signedTransaction = await Evm.reconstructSignedTXFromLocalSession(
+ big_r,
+ s,
+ recovery_id,
+ senderAddress
+ );
+
+ setSignedTransaction(signedTransaction);
+ setStatus(
+ "✅ Signed payload ready to be relayed to the Base network"
+ );
+ setStep("relay");
+
+ setReloaded(false);
+ removeUrlParams();
+ }
+ }, [senderAddress, reloaded, wallet, setStatus]);
+
+ // Handle changes to derivation path and query Base address and balance
+ useEffect(() => {
+ resetAddressState();
+ fetchEthereumAddress();
+ }, [derivationPath, signedAccountId]);
+
+ const resetAddressState = () => {
+ setSenderLabel("Waiting for you to stop typing...");
+ setSenderAddress(null);
+ setStatus("");
+ setBalance(""); // Reset balance when derivation path changes
+ setStep("request");
+ };
+
+ const fetchEthereumAddress = async () => {
+ const { address } = await Evm.deriveAddress(
+ signedAccountId,
+ derivationPath
+ );
+ setSenderAddress(address);
+ setSenderLabel(address);
+
+ if (!reloaded) {
+ const balance = await Evm.getBalance(address);
+ setBalance(balance); // Update balance state
+ }
+ };
+
+ async function chainSignature() {
+ setStatus("🏗️ Creating transaction");
+
+ const { transaction } = await childRef.current.createTransaction();
+
+ setStatus(
+ `🕒 Asking ${MPC_CONTRACT} to sign the transaction, this might take a while`
+ );
+ try {
+ // to reconstruct on reload
+ sessionStorage.setItem("derivation", derivationPath);
+
+ const { big_r, s, recovery_id } = await Evm.requestSignatureToMPC({
+ wallet,
+ path: derivationPath,
+ transaction,
+ });
+ const signedTransaction = await Evm.reconstructSignedTransaction(
+ big_r,
+ s,
+ recovery_id,
+ transaction
+ );
+
+ setSignedTransaction(signedTransaction);
+ setStatus(
+ `✅ Signed payload ready to be relayed to the Base network`
+ );
+ setStep("relay");
+ } catch (e) {
+ setStatus(`❌ Error: ${e.message}`);
+ setLoading(false);
+ }
+ }
+
+ async function relayTransaction() {
+ setLoading(true);
+ setStatus(
+ "🔗 Relaying transaction to the Base network... this might take a while"
+ );
+
+ try {
+ const txHash = await Evm.broadcastTX(signedTransaction);
+ setStatus(
+ <>
+
+ {" "}
+ ✅ Successful{" "}
+
+ >
+ );
+ childRef.current.afterRelay();
+ } catch (e) {
+ setStatus(`❌ Error: ${e.message}`);
+ }
+
+ setStep("request");
+ setLoading(false);
+ }
+
+ const UIChainSignature = async () => {
+ setLoading(true);
+ await chainSignature();
+ setLoading(false);
+ };
+
+ function removeUrlParams() {
+ const url = new URL(window.location.href);
+ url.searchParams.delete("transactionHashes");
+ window.history.replaceState({}, document.title, url);
+ }
+
+ return (
+ <>
+ {/* Form Inputs */}
+
+
+
+
+ PATH
+
+ setDerivation(e.target.value)}
+ disabled={loading}
+ />
+
+
+ {/* ADDRESS & BALANCE */}
+
+
+
+
+
+
+ {balance ? (
+ `${balance} ETH`
+ ) : (
+ Fetching balance...
+ )}
+
+
+
+
+
+
+
+ ACTION
+
+
+
+
+ {action === "transfer" ? (
+
+ ) : (
+
+ )}
+
+
+
+
+
+ Sepolia Gas Prices
+
+
+
+ Price |
+ Unit |
+
+
+
+
+ {gasPriceInGwei} |
+ GWEI |
+
+
+ {txCost} |
+ ETH |
+
+
+
+
+
+
+ {/* Execute Buttons */}
+
+ {step === "request" && (
+
+ )}
+ {step === "relay" && (
+
+ )}
+
+ >
+ );
+}
+
+BaseView.propTypes = {
+ props: PropTypes.shape({
+ setStatus: PropTypes.func.isRequired,
+ MPC_CONTRACT: PropTypes.string.isRequired,
+ }).isRequired,
+};
diff --git a/src/components/Ethereum/Ethereum.jsx b/src/components/EVM/Ethereum.jsx
similarity index 91%
rename from src/components/Ethereum/Ethereum.jsx
rename to src/components/EVM/Ethereum.jsx
index 1c13828..e6b61f3 100644
--- a/src/components/Ethereum/Ethereum.jsx
+++ b/src/components/EVM/Ethereum.jsx
@@ -2,14 +2,15 @@ import { useState, useEffect, useContext, useRef } from "react";
import PropTypes from "prop-types";
import { NearContext } from "../../context";
-import { Ethereum } from "../../services/ethereum";
import { useDebounce } from "../../hooks/debounce";
import { getTransactionHashes } from "../../services/utils";
import { TransferForm } from "./Transfer";
import { FunctionCallForm } from "./FunctionCall";
+import { EthereumVM } from "../../services/evm";
-const Sepolia = 11155111;
-const Eth = new Ethereum("https://sepolia.drpc.org", Sepolia);
+const Evm = new EthereumVM("https://sepolia.drpc.org");
+
+const contractAddress = "0xe2a01146FFfC8432497ae49A7a6cBa5B9Abd71A3";
const transactions = getTransactionHashes();
@@ -38,10 +39,10 @@ export function EthereumView({ props: { setStatus, MPC_CONTRACT } }) {
async function fetchEthereumGasPrice() {
try {
// Fetch gas price in Wei
- const gasPriceInWei = await Eth.web3.eth.getGasPrice();
+ const gasPriceInWei = await Evm.web3.eth.getGasPrice();
// Convert gas price from Wei to Gwei
- const gasPriceInGwei = Eth.web3.utils.fromWei(gasPriceInWei, "gwei");
+ const gasPriceInGwei = Evm.web3.utils.fromWei(gasPriceInWei, "gwei");
// Gas limit for a standard ETH transfer
const gasLimit = 21000;
@@ -78,12 +79,13 @@ export function EthereumView({ props: { setStatus, MPC_CONTRACT } }) {
const { big_r, s, recovery_id } = await wallet.getTransactionResult(
transactions[0]
);
- const signedTransaction = await Eth.reconstructSignedTXFromLocalSession(
+ const signedTransaction = await Evm.reconstructSignedTXFromLocalSession(
big_r,
s,
recovery_id,
senderAddress
);
+
setSignedTransaction(signedTransaction);
setStatus(
"✅ Signed payload ready to be relayed to the Ethereum network"
@@ -110,7 +112,7 @@ export function EthereumView({ props: { setStatus, MPC_CONTRACT } }) {
};
const fetchEthereumAddress = async () => {
- const { address } = await Eth.deriveAddress(
+ const { address } = await Evm.deriveAddress(
signedAccountId,
derivationPath
);
@@ -118,11 +120,11 @@ export function EthereumView({ props: { setStatus, MPC_CONTRACT } }) {
setSenderLabel(address);
if (!reloaded) {
- const balance = await Eth.getBalance(address);
+ const balance = await Evm.getBalance(address);
setBalance(balance); // Update balance state
}
};
-
+
async function chainSignature() {
setStatus("🏗️ Creating transaction");
@@ -135,12 +137,12 @@ export function EthereumView({ props: { setStatus, MPC_CONTRACT } }) {
// to reconstruct on reload
sessionStorage.setItem("derivation", derivationPath);
- const { big_r, s, recovery_id } = await Eth.requestSignatureToMPC({
+ const { big_r, s, recovery_id } = await Evm.requestSignatureToMPC({
wallet,
path: derivationPath,
transaction,
});
- const signedTransaction = await Eth.reconstructSignedTransaction(
+ const signedTransaction = await Evm.reconstructSignedTransaction(
big_r,
s,
recovery_id,
@@ -165,7 +167,7 @@ export function EthereumView({ props: { setStatus, MPC_CONTRACT } }) {
);
try {
- const txHash = await Eth.broadcastTX(signedTransaction);
+ const txHash = await Evm.broadcastTX(signedTransaction);
setStatus(
<>
@@ -256,11 +258,11 @@ export function EthereumView({ props: { setStatus, MPC_CONTRACT } }) {
{action === "transfer" ? (
-
+
) : (
)}
diff --git a/src/components/EVM/FunctionCall.jsx b/src/components/EVM/FunctionCall.jsx
new file mode 100644
index 0000000..7b30a3c
--- /dev/null
+++ b/src/components/EVM/FunctionCall.jsx
@@ -0,0 +1,139 @@
+import { useState, useEffect } from "react";
+
+import PropTypes from "prop-types";
+import { forwardRef } from "react";
+import { useImperativeHandle } from "react";
+
+const abi = [
+ {
+ inputs: [
+ {
+ internalType: "uint256",
+ name: "_num",
+ type: "uint256",
+ },
+ ],
+ name: "set",
+ outputs: [],
+ stateMutability: "nonpayable",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "get",
+ outputs: [
+ {
+ internalType: "uint256",
+ name: "",
+ type: "uint256",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [],
+ name: "num",
+ outputs: [
+ {
+ internalType: "uint256",
+ name: "",
+ type: "uint256",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+];
+
+export const FunctionCallForm = forwardRef(
+ ({ props: { Evm, contractAddress, senderAddress, loading } }, ref) => {
+ const [number, setNumber] = useState(1000);
+ const [currentNumber, setCurrentNumber] = useState("");
+
+ async function getNumber() {
+ const result = await Evm.getContractViewFunction(
+ contractAddress,
+ abi,
+ "get"
+ );
+ setCurrentNumber(String(result));
+ }
+
+ useEffect(() => {
+ getNumber();
+ }, []);
+
+ useImperativeHandle(ref, () => ({
+ async createTransaction() {
+ const data = Evm.createTransactionData(contractAddress, abi, "set", [
+ number,
+ ]);
+ const { transaction } = await Evm.createTransaction({
+ sender: senderAddress,
+ receiver: contractAddress,
+ amount: 0,
+ data,
+ });
+ return { transaction };
+ },
+
+ async afterRelay() {
+ getNumber();
+ },
+ }));
+
+ return (
+ <>
+
+
+
+
+
setNumber(e.target.value)}
+ step="1"
+ disabled={loading}
+ />
+
+ {" "}
+ The number to save, current value: {currentNumber} {" "}
+
+
+
+ >
+ );
+ }
+);
+
+FunctionCallForm.propTypes = {
+ props: PropTypes.shape({
+ senderAddress: PropTypes.string.isRequired,
+ contractAddress: PropTypes.string.isRequired,
+ loading: PropTypes.bool.isRequired,
+ Evm: PropTypes.shape({
+ createTransaction: PropTypes.func.isRequired,
+ createTransactionData: PropTypes.func.isRequired,
+ getContractViewFunction: PropTypes.func.isRequired,
+ }).isRequired,
+ }).isRequired,
+};
+
+FunctionCallForm.displayName = "FunctionCallForm";
diff --git a/src/components/Ethereum/Transfer.jsx b/src/components/EVM/Transfer.jsx
similarity index 70%
rename from src/components/Ethereum/Transfer.jsx
rename to src/components/EVM/Transfer.jsx
index 2edfaff..c56c984 100644
--- a/src/components/Ethereum/Transfer.jsx
+++ b/src/components/EVM/Transfer.jsx
@@ -4,24 +4,16 @@ import PropTypes from "prop-types";
import { forwardRef } from "react";
import { useImperativeHandle } from "react";
-export const TransferForm = forwardRef(
- ({ props: { Eth, senderAddress, loading } }, ref) => {
- const [receiver, setReceiver] = useState(
- "0x427F9620Be0fe8Db2d840E2b6145D1CF2975bcaD"
- );
- const [amount, setAmount] = useState(0.005);
+export const TransferForm = forwardRef(({ props: { Evm, senderAddress, loading } }, ref) => {
+ const [receiver, setReceiver] = useState("0xb8A6a4eb89b27703E90ED18fDa1101c7aa02930D");
+ const [amount, setAmount] = useState(0.005);
- useImperativeHandle(ref, () => ({
- async createTransaction() {
- return await Eth.createTransaction({
- sender: senderAddress,
- receiver: receiver,
- amount: amount,
- data: undefined,
- });
- },
- async afterRelay() {},
- }));
+ useImperativeHandle(ref, () => ({
+ async createTransaction() {
+ return await Evm.createTransaction({ sender: senderAddress, receiver, amount });
+ },
+ async afterRelay() { }
+ }));
return (
<>
@@ -70,10 +62,10 @@ TransferForm.propTypes = {
props: PropTypes.shape({
senderAddress: PropTypes.string.isRequired,
loading: PropTypes.bool.isRequired,
- Eth: PropTypes.shape({
- createTransaction: PropTypes.func.isRequired,
- }).isRequired,
- }).isRequired,
+ Evm: PropTypes.shape({
+ createTransaction: PropTypes.func.isRequired
+ }).isRequired
+ }).isRequired
};
TransferForm.displayName = "TransferForm";
diff --git a/src/components/Ethereum/FunctionCall.jsx b/src/components/Ethereum/FunctionCall.jsx
deleted file mode 100644
index 385ed5a..0000000
--- a/src/components/Ethereum/FunctionCall.jsx
+++ /dev/null
@@ -1,118 +0,0 @@
-import { useState, useEffect } from 'react';
-
-import PropTypes from 'prop-types';
-import { forwardRef } from 'react';
-import { useImperativeHandle } from 'react';
-
-const abi = [
- {
- inputs: [
- {
- internalType: 'uint256',
- name: '_num',
- type: 'uint256',
- },
- ],
- name: 'set',
- outputs: [],
- stateMutability: 'nonpayable',
- type: 'function',
- },
- {
- inputs: [],
- name: 'get',
- outputs: [
- {
- internalType: 'uint256',
- name: '',
- type: 'uint256',
- },
- ],
- stateMutability: 'view',
- type: 'function',
- },
- {
- inputs: [],
- name: 'num',
- outputs: [
- {
- internalType: 'uint256',
- name: '',
- type: 'uint256',
- },
- ],
- stateMutability: 'view',
- type: 'function',
- },
-];
-
-const contract = '0xe2a01146FFfC8432497ae49A7a6cBa5B9Abd71A3';
-
-export const FunctionCallForm = forwardRef(({ props: { Eth, senderAddress, loading } }, ref) => {
- const [number, setNumber] = useState(1000);
- const [currentNumber, setCurrentNumber] = useState('');
-
- async function getNumber() {
- const result = await Eth.getContractViewFunction(contract, abi, 'get');
- setCurrentNumber(String(result));
- }
-
- useEffect(() => { getNumber() }, []);
-
- useImperativeHandle(ref, () => ({
- async createTransaction() {
- const data = Eth.createTransactionData(contract, abi, 'set', [number]);
- const { transaction } = await Eth.createTransaction({ sender: senderAddress, receiver: contract, amount: 0, data });
- return { transaction };
- },
-
- async afterRelay() { getNumber(); }
- }));
-
- return (
- <>
-
-
-
-
-
setNumber(e.target.value)}
- step="1"
- disabled={loading}
- />
-
The number to save, current value: {currentNumber}
-
-
- >
- );
-});
-
-FunctionCallForm.propTypes = {
- props: PropTypes.shape({
- senderAddress: PropTypes.string.isRequired,
- loading: PropTypes.bool.isRequired,
- Eth: PropTypes.shape({
- createTransaction: PropTypes.func.isRequired,
- createTransactionData: PropTypes.func.isRequired,
- getContractViewFunction: PropTypes.func.isRequired,
- }).isRequired,
- }).isRequired
-};
-
-FunctionCallForm.displayName = 'EthereumContractView';
\ No newline at end of file
diff --git a/src/services/ethereum.js b/src/services/evm.js
similarity index 62%
rename from src/services/ethereum.js
rename to src/services/evm.js
index 7125074..d94cacd 100644
--- a/src/services/ethereum.js
+++ b/src/services/evm.js
@@ -1,22 +1,23 @@
-import { Web3 } from 'web3';
-import { bytesToHex } from '@ethereumjs/util';
-import { FeeMarketEIP1559Transaction } from '@ethereumjs/tx';
-import { generateEthAddress } from './kdf/eth';
-import { Common } from '@ethereumjs/common'
+import { Web3 } from "web3";
+import { bytesToHex } from "@ethereumjs/util";
+import { FeeMarketEIP1559Transaction } from "@ethereumjs/tx";
+import { generateEthAddress } from "./kdf/eth";
import { Contract, JsonRpcProvider } from "ethers";
import { MPC_CONTRACT } from "./kdf/mpc";
-export class Ethereum {
- constructor(chain_rpc, chain_id) {
- this.web3 = new Web3(chain_rpc);
+export class EthereumVM {
+ constructor(chain_rpc) {
+ this.web3 = new Web3(new Web3.providers.HttpProvider(chain_rpc));
window.web3 = this.web3;
this.provider = new JsonRpcProvider(chain_rpc);
- this.chain_id = chain_id;
this.queryGasPrice();
}
async deriveAddress(accountId, derivation_path) {
- const { address, publicKey } = await generateEthAddress({ accountId, derivation_path });
+ const { address, publicKey } = await generateEthAddress({
+ accountId,
+ derivation_path,
+ });
return { address, publicKey };
}
@@ -45,12 +46,12 @@ export class Ethereum {
}
async createTransaction({ sender, receiver, amount, data = undefined }) {
- const common = new Common({ chain: this.chain_id });
-
// Get the nonce & gas price
const nonce = await this.web3.eth.getTransactionCount(sender);
const { maxFeePerGas, maxPriorityFeePerGas } = await this.queryGasPrice();
+ const { chainId } = await this.provider.getNetwork();
+
// Construct transaction
const transactionData = {
nonce,
@@ -59,50 +60,72 @@ export class Ethereum {
maxPriorityFeePerGas,
to: receiver,
data: data,
- value: BigInt(this.web3.utils.toWei(amount, 'ether')),
- chain: this.chain_id,
+ value: BigInt(this.web3.utils.toWei(amount, "ether")),
+ chainId: chainId,
};
// Create a transaction
- const transaction = FeeMarketEIP1559Transaction.fromTxData(transactionData, { common });
+ const transaction = FeeMarketEIP1559Transaction.fromTxData(
+ transactionData,
+ {}
+ );
// Store in sessionStorage for later
- sessionStorage.setItem('transaction', transaction.serialize());
+ sessionStorage.setItem("transaction", transaction.serialize());
return { transaction };
}
- async requestSignatureToMPC({ wallet, path, transaction, attachedDeposit = 1 }) {
+ async requestSignatureToMPC({
+ wallet,
+ path,
+ transaction,
+ attachedDeposit = 1,
+ }) {
const payload = Array.from(transaction.getHashedMessageToSign());
const { big_r, s, recovery_id } = await wallet.callMethod({
contractId: MPC_CONTRACT,
- method: 'sign',
+ method: "sign",
args: { request: { payload, path, key_version: 0 } },
- gas: '250000000000000', // 250 Tgas
+ gas: "250000000000000", // 250 Tgas
deposit: attachedDeposit,
});
- return { big_r, s, recovery_id };
+ return {
+ big_r,
+ s,
+ recovery_id,
+ };
}
async reconstructSignedTransaction(big_r, S, recovery_id, transaction) {
// reconstruct the signature
- const r = Buffer.from(big_r.affine_point.substring(2), 'hex');
- const s = Buffer.from(S.scalar, 'hex');
+ const r = Buffer.from(big_r.affine_point.substring(2), "hex");
+ const s = Buffer.from(S.scalar, "hex");
const v = recovery_id;
const signedTx = transaction.addSignature(v, r, s);
- if (signedTx.getValidationErrors().length > 0) throw new Error("Transaction validation errors");
+ if (signedTx.getValidationErrors().length > 0)
+ throw new Error("Transaction validation errors");
if (!signedTx.verifySignature()) throw new Error("Signature is not valid");
return signedTx;
}
async reconstructSignedTXFromLocalSession(big_r, s, recovery_id, sender) {
- const serialized = Uint8Array.from(JSON.parse(`[${sessionStorage.getItem('transaction')}]`));
- const transaction = FeeMarketEIP1559Transaction.fromSerializedTx(serialized);
- return this.reconstructSignedTransaction(big_r, s, recovery_id, transaction, sender);
+ const serialized = Uint8Array.from(
+ JSON.parse(`[${sessionStorage.getItem("transaction")}]`)
+ );
+ const transaction =
+ FeeMarketEIP1559Transaction.fromSerializedTx(serialized);
+ return this.reconstructSignedTransaction(
+ big_r,
+ s,
+ recovery_id,
+ transaction,
+ sender
+ );
}
// This code can be used to actually relay the transaction to the Ethereum network
@@ -110,7 +133,9 @@ export class Ethereum {
const serializedTx = bytesToHex(signedTransaction.serialize());
const relayed = this.web3.eth.sendSignedTransaction(serializedTx);
let txHash;
- await relayed.on('transactionHash', (hash) => { txHash = hash });
+ await relayed.on("transactionHash", (hash) => {
+ txHash = hash;
+ });
return txHash;
}
}