WAGMI
#Overview
WAGMI is a development library that streamlines Ethereum development. Popular among developers for its ease in managing multiple wallets, it becomes even more powerful when combined with Magic. This integration streamlines user interactions across various wallets while leveraging Magic's blazing-fast and secure passwordless login. This guide details the integration process using Magic's DedicatedWalletConnector
using WAGMI v1 and v2.
#Installation
Depending on your project's setup, you may be using different versions of WAGMI. Below, you'll find commands for both WAGMI v1 and v2 installations.
Add the required dependencies using your chosen package manager.
WAGMI v1
01npm install wagmi@1.4.12 @magiclabs/wagmi-connector@1.1.5
WAGMI v2
01npm install wagmi @magiclabs/wagmi-connector @tanstack/react-query viem
#Initialization
This process varies slightly between WAGMI v1 and v2 due to differences in package structure and functionality. The initialization step is critical as it lays the foundation for your application's blockchain interactions.
To initialize, import the necessary dependencies from Magic and WAGMI in your root file (i.e. App.tsx
). Next, add the Magic DedicatedWalletConnector
and its configuration as the connectors
value of the config.
Finally, pass the configuration to the WagmiConfig
component to make WAGMI hooks available across the whole application.
01import { configureChains, createConfig, WagmiConfig } from "wagmi";
02import { mainnet } from "wagmi/chains";
03import { publicProvider } from "wagmi/providers/public";
04import { DedicatedWalletConnector } from "@magiclabs/wagmi-connector";
05import Dashboard from "./components/Dashboard";
06
07const { chains, publicClient, webSocketPublicClient } = configureChains(
08 [mainnet],
09 [publicProvider()]
10);
11
12const config = createConfig({
13 autoConnect: true,
14 publicClient,
15 webSocketPublicClient,
16 connectors: [
17 new DedicatedWalletConnector({
18 chains,
19 options: {
20 apiKey: "PUBLISHABLE_API_KEY",
21 isDarkMode: true,
22 /* If using OAuth, make sure to enable OAuth options from magic dashboard */
23 oauthOptions: {
24 providers: [""],
25 },
26 magicSdkConfiguration: {
27 network: {
28 rpcUrl: RPC_URL,
29 chainId: CHAIN_ID,
30 },
31 },
32 },
33 }),
34 ],
35});
36
37function App() {
38 return (
39 <WagmiConfig config={config}>
40 <Dashboard />
41 </WagmiConfig>
42 );
43}
44
45export default App;
#Usage
This section covers common tasks such as connecting to the Ethereum network, signing messages, sending transactions, and checking wallet balances.
With the Magic connector added, you can use WAGMI hooks for everything else per their documentation.
Some of the functions do not differ between WAGMI versions
#Connect to the network
How to use WAGMI's hooks to connect a user's wallet to the Ethereum network, enabling them to interact with your application.
01import { useConnect } from 'wagmi'
02
03const SignIn = () => {
04 const { connect, connectors, isLoading, isIdle } = useConnect()
05
06 return (
07 <div className="sign-in-container">
08 <button
09 onClick={() => connect({ connector: connectors[0] })}
10 >
11 {isLoading ? "Loading..." : isIdle ? "Connect" : "Connecting..."}
12 </button>
13 </div>
14 )
15}
16
17export default SignIn
#Sign message
How to prompt users to sign a message with their private key, a common method for authenticating users and verifying their actions without executing transactions.
01import { useSignMessage } from 'wagmi'
02
03function Component() {
04 const { data, isError, isLoading, isSuccess, signMessage } = useSignMessage({
05 message: 'Signed from Magic',
06 })
07
08 return (
09 <div>
10 <button disabled={isLoading} onClick={() => signMessage()}>
11 Sign message
12 </button>
13 {isSuccess && <div>Signature: {data}</div>}
14 {isError && <div>Error signing message</div>}
15 </div>
16 )
17}
#Send transaction
How to create and send transactions to the Ethereum network, allowing users to transfer ETH or interact with smart contracts.
01import { parseEther } from "ethers/lib/utils.js";
02import { useState } from "react";
03import {
04 useSendTransaction,
05 usePrepareSendTransaction,
06 useWaitForTransaction,
07} from "wagmi";
08import { useDebounce } from "use-debounce";
09
10const SendTransaction = () => {
11 const [address, setAddress] = useState(
12 "0x8bdCE5551B544AF8dFfB09Ff34c34da7FC241Bd0"
13 );
14 const [debouncedAddress] = useDebounce(address, 500);
15 const [amount, setAmount] = useState("0.01");
16 const [debouncedAmount] = useDebounce(amount, 500);
17
18 const { config, error } = usePrepareSendTransaction({
19 request: {
20 to: debouncedAddress,
21 value: debouncedAmount ? parseEther(debouncedAmount) : undefined,
22 },
23 });
24
25 const { data, sendTransaction } = useSendTransaction(config);
26
27 const { isLoading, isSuccess } = useWaitForTransaction({
28 hash: data?.hash,
29 });
30
31 return (
32 <div>
33 <form
34 onSubmit={(e) => {
35 e.preventDefault();
36 sendTransaction?.();
37 }}
38 >
39 <input
40 value={address}
41 placeholder="Receiving Address"
42 onChange={(e) => setAddress(e.target.value)}
43 />
44 <input
45 value={amount}
46 placeholder="Amount of ETH"
47 onChange={(e) => setAmount(e.target.value)}
48 />
49 <button
50 disabled={isLoading || !sendTransaction || !address || !amount}
51 type="submit"
52 >
53 {isLoading ? "Sending..." : "Send"}
54 </button>
55 {isSuccess && (
56 <div>
57 Successfully sent {amount} ether to {address}. View transaction on{" "}
58 <a
59 href={`https://goerli.etherscan.io/tx/${data?.hash}`}
60 target="_blank"
61 rel="noreferrer"
62 >
63 Etherscan
64 </a>
65 </div>
66 )}
67 {error && (
68 <div>
69 An error occurred preparing the transaction: {error.message}
70 </div>
71 )}
72 </form>
73 </div>
74 );
75};
76
77export default SendTransaction;
#Check balance
How to check and display the ETH balance of a given address, providing insight to a user's wallet state.
01import { useBalance } from 'wagmi'
02
03function Component() {
04 const { data, isError, isLoading } = useBalance({
05 address: 'example.eth',
06 })
07
08 if (isLoading) return <div>Fetching balance…</div>
09 if (isError) return <div>Error fetching balance</div>
10 return (
11 <div>
12 Balance: {data?.formatted} {data?.symbol}
13 </div>
14 )
15}