I am trying to migrate my metamask wallet connect code from using window.etherum to metamask SDK for future potential mobile users.
And I am running into a major issue that seems like the accountsChanged event cannot be listened by metamask.on.
The following example nextjs code is able to replicate this issue.
"use client";
import { MetaMaskSDK } from "@metamask/sdk";
import { useState } from "react";
export default function Home() {
const [metamask, setMetamask] = useState<MetaMaskSDK | void>(undefined);
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<div
onClick={() => {
getWalletFromWindow().then(setMetamask);
}}
>
getSDK
</div>
{metamask ? (
<div
onClick={() =>
metamask.connect().then((accounts) => {
console.log("Connected, accounts:", accounts);
})
}
>
Connect
</div>
) : null}
{metamask ? (
<div
onClick={() => {
console.log(metamask);
metamask.on("accountsChanged", (a) =>
console.log("Account Changed ", a)
);
}}
>
Add change event
</div>
) : null}
</main>
);
}
const getWalletFromWindow = async (): Promise<MetaMaskSDK | void> => {
if (typeof window === "undefined") {
throw new Error("Cannot get Metamask without a window");
}
const MMSDK = new MetaMaskSDK({
dappMetadata: {
name: "Example Node.js Dapp",
url: window.location.href,
},
// Other options
});
const metamask = await MMSDK.init();
if (metamask)
metamask.on("accountsChanged", (accounts) =>
console.log("accounts changed listened by metamask.on", accounts)
);
// @ts-ignore
window.ethereum.on("accountsChanged", (accounts) =>
console.log("accounts changed listened by window.ethereum.on", accounts)
);
return metamask;
};
In the runtime of above code, the accountsChanged event can be detected by the window.ethereum.on listener but not SDK object metamask.on listener. See the video herewith.
Appreciate if any hint could be given.