guides
Guide

How to use Magic with Ethereum and Optimism

Magic Staff ยท August 1, 2021

#Resources

Note: this guide uses web3.js, but to see a demo with ethers.js click here.

#Introduction

#What is Optimism

Optimism (aka Optimistic Ethereum) is a Layer 2 scaling solution for Ethereum. It uses "optimistic rollups" technology where transactions are submitted directly to the L2, "rolled up" into a single proof, then sent to the layer one chain (Ethereum) to be verified. With smart contract computations being done on L2 rather than L1, it allows for significantly faster and cheaper transactions.

Optimism is also interoperable with Ethereum and the Ethereum Virtual Machine (EVM) so smart contracts can easily be deployed on Optimism without much/any refactoring.

With Magic, developers can connect to the Optimism network by simply specifying the network URL when initiating a Magic instance. This guide will show how you can create a web3-enabled app, allow users to switch between the Ethereum and Optimism networks, call smart contracts, and send transactions.

#Connecting to Optimism

In magic.js, simply initialize the Magic instance with the network pointed to your Optimism rpc url.

import { Magic } from "magic-sdk";

const customNodeOptions = {
  rpcUrl: "https://goerli.optimism.io",
  chainId: 420
};

export const magic = new Magic("YOUR_API_KEY", {
  network: customNodeOptions
});

#Viewing User Balance

You can use the native getBalance function of the web3.js library to pull the user's balance for whichever network you iniated Magic with.

const fetchBalance = (address) => {
  web3.eth.getBalance(address).then(bal => setBalance(web3.utils.fromWei(bal)))
}

return (
  <h1>Balance</h1>
  <div className="info">
    {balance.toString().substring(0, 6)} ETH
  </div>
)

#Send Transaction

Sending a transaction is also very simple using web3.js. Be sure to pass in a gasPrice as Optimism does not accept EIP-1559 transactions, and if there is no gasPrice specified, Magic will manually calculate it using an EIP-1559 transaction type.

const sendTransaction = async () => {
    const { transactionHash } = await web3.eth.sendTransaction({
      from: publicAddress,
      to: toAddress,
      value: web3.utils.toWei(amount),
      gasPrice: "1"
    });
}

return (
 <div className="container">
  <h1>Send Transaction</h1>
  <input 
    type="text" 
    value={toAddress} 
    onChange={(e) => setToAddress(e.target.value)} 
    placeholder="To Address" 
  />
  <input 
    type="text" 
    value={amount} 
    onChange={(e) => setAmount(e.target.value)} 
    placeholder="Amount" 
  />
  <button onClick={sendTransaction}>Send Transaction</button>
</div>
)

#Calling Smart Contracts

const contractAddress = "0x6fA26B7618881A5D528dff280d5A12c51CDD41b8";
  const contract = new web3.eth.Contract(abi, contractAddress);
  const [number, setNumber] = useState();
  const [newNumber, setNewNumber] = useState("");

  const fetchContractNumber = () => {
    contract.methods.number().call().then(setNumber);
  };

  useEffect(() => {
    fetchContractNumber();
  }, []);

  const updateContractNumber = async () => {
    const { transactionHash } = await contract.methods.store(newNumber).send({
      from: publicAddress,
      gasPrice: "1"
    });
  };

  return (
    <div className="container">
      <h1>Number stored in contract</h1>
      <div className="info">{number}</div>

      <h1>Update Number</h1>
      <input
        type="text"
        disabled={disabled}
        value={newNumber}
        onChange={(e) => setNewNumber(e.target.value)}
        className="full-width"
        placeholder="New number"
      />
      <button disabled={disabled} onClick={updateContractNumber}>
        Update
      </button>
    </div>
  );

#Done

That's all there is to it! You've now got an app that allows users to create a wallet with just their email, and connect to the Optimism L2 and Ethereum networks within your app.

Let's make some magic!

Did you find what you were looking for?