How to use Magic with Ethereum and Arbitrum
#Resources
Note: this guide uses web3.js, but to see a demo with ethers.js click here.
#Introduction
#What is Arbitrum?
Arbitrum is a Layer 2 scaling solution for Ethereum, which launched in May 2021. 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. Arbitrum is also interoperable with Ethereum and the Ethereum Virtual Machine (EVM) so smart contracts can easily be deployed on Arbitrum without much/any refactoring. With Magic, developers can connect to the Arbitrum 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 Arbitrum networks, call smart contracts, and send transactions.
#Connecting to Arbitrum
In magic.js
, simply initialize the Magic instance with the network
pointed to your Arbitrum rpc url.
01import { Magic } from "magic-sdk";
02
03const customNodeOptions = {
04 rpcUrl: "https://goerli-rollup.arbitrum.io/rpc",
05 chainId: 421613
06};
07
08export const magic = new Magic("YOUR_API_KEY", {
09 network: customNodeOptions
10});
#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.
01const fetchBalance = (address) => {
02 web3.eth.getBalance(address).then(bal => setBalance(web3.utils.fromWei(bal)))
03}
04
05return (
06 <h1>Balance</h1>
07 <div className="info">
08 {balance.toString().substring(0, 6)} ETH
09 </div>
10)
#Send Transaction
Sending a transaction is also very simple using web3.js.
01const sendTransaction = async () => {
02 const { transactionHash } = await web3.eth.sendTransaction({
03 from: publicAddress,
04 to: toAddress,
05 value: web3.utils.toWei(amount)
06 });
07}
08
09return (
10 <div className="container">
11 <h1>Send Transaction</h1>
12 <input
13 type="text"
14 value={toAddress}
15 onChange={(e) => setToAddress(e.target.value)}
16 placeholder="To Address"
17 />
18 <input
19 type="text"
20 value={amount}
21 onChange={(e) => setAmount(e.target.value)}
22 placeholder="Amount"
23 />
24 <button onClick={sendTransaction}>Send Transaction</button>
25</div>
26)
#Calling Smart Contracts
01const contractAddress = "0x8e37B2da4D634bE57667326dEBe0c52798753CEf";
02 const contract = new web3.eth.Contract(abi, contractAddress);
03 const [number, setNumber] = useState();
04 const [newNumber, setNewNumber] = useState("");
05
06 const fetchContractNumber = () => {
07 contract.methods.number().call().then(setNumber);
08 };
09
10 useEffect(() => {
11 fetchContractNumber();
12 }, []);
13
14 const updateContractNumber = async () => {
15 const { transactionHash } = await contract.methods.store(newNumber).send({
16 from: publicAddress
17 });
18 };
19
20 return (
21 <div className="container">
22 <h1>Number stored in contract</h1>
23 <div className="info">{number}</div>
24
25 <h1>Update Number</h1>
26 <input
27 type="text"
28 disabled={disabled}
29 value={newNumber}
30 onChange={(e) => setNewNumber(e.target.value)}
31 className="full-width"
32 placeholder="New number"
33 />
34 <button disabled={disabled} onClick={updateContractNumber}>
35 Update
36 </button>
37 </div>
38 );
#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 Arbitrum L2 and Ethereum networks within your app.