Allow WalletConnect to change accounts and network

Signed-off-by: Sebastian Martinez <sebastinez@me.com>
This commit is contained in:
Sebastian Martinez
2021-11-15 14:48:21 +01:00
parent 54df789c95
commit c5172b8cc5
3 changed files with 38 additions and 18 deletions
+6 -1
View File
@@ -7,6 +7,7 @@ import { Core } from '@self.id/core';
import WalletConnect from "@walletconnect/client";
import config from "@app/config.json";
import { WalletConnectSigner } from "./WalletConnectSigner";
import { disconnectWallet } from "./session";
declare global {
interface Window {
@@ -129,6 +130,10 @@ export class Config {
);
}
changeNetwork(chainId: number): void {
this.network = ethers.providers.getNetwork(chainId);
}
setSigner(signer: ethers.Signer & TypedDataSigner | WalletConnectSigner): void {
this.signer = signer;
}
@@ -210,7 +215,7 @@ export class Config {
}
}
function isMetamaskInstalled(): boolean {
export function isMetamaskInstalled(): boolean {
const { ethereum } = window;
return Boolean(ethereum && ethereum.isMetaMask);
}
+32 -8
View File
@@ -2,9 +2,8 @@ import { get, writable, derived } from "svelte/store";
import type { Readable } from "svelte/store";
import type { BigNumber } from 'ethers';
import type { TransactionReceipt, TransactionResponse } from '@ethersproject/providers';
import { Config, getConfig } from "@app/config";
import { Config, getConfig, isMetamaskInstalled } from "@app/config";
import { Unreachable, assert, assertEq } from "@app/error";
import { formatNetwork } from "@app/utils";
import * as ethers from "ethers";
export enum Connection {
@@ -105,12 +104,34 @@ export const loadState = (initial: State): Store => {
signer.walletConnect.chainId
);
// Instead of killing the WalletConnect session, we force the UI to change network
if (network.chainId !== config.network.chainId) {
config.walletConnect.client.killSession();
throw new Error(
`Network mismatch. Please switch your wallet to ${formatNetwork(config.network)}.`
);
config.changeNetwork(network.chainId);
}
config.walletConnect.client.on("session_update", async (error, { params: [{ accounts, chainId }] }: { params: [{ accounts: [string]; chainId: number }] }) => {
if (error) {
throw error;
}
try {
// We only change accounts if the address has been changed, to avoid unnecessary refreshing.
if (address !== accounts[0]) changeAccounts(accounts[0]);
// Check the current chainId, and request Metamask to change, or reload the window to get the correct chain.
if (chainId !== config.network.chainId) {
if (isMetamaskInstalled()) {
await window.ethereum.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: ethers.utils.hexValue(chainId) }]
});
} else {
config.changeNetwork(chainId);
window.location.reload();
}
}
} catch (e) { console.error(e); }
});
store.set({ connection: Connection.Connected, session });
} catch (e) {
console.log("WalletConnect: connection failed.");
@@ -245,15 +266,18 @@ window.ethereum?.on('chainChanged', () => {
// We disconnect the wallet to avoid out of sync state
// between the account address and IDX DIDs
disconnectMetamask();
location.reload();
});
// Updates state when user changes accounts
window.ethereum?.on("accountsChanged", async ([address]: string) => {
changeAccounts(address);
});
export async function changeAccounts(address: string): Promise<void> {
const config = await getConfig();
state.setChangedAccount(address);
state.refreshBalance(config);
});
}
state.subscribe(s => {
console.log("session.state", s);
-9
View File
@@ -107,15 +107,6 @@ export function formatHash(hash: string): string {
+ hash.substring(hash.length - 4, hash.length);
}
export function formatNetwork(input: { name: string }): string {
let name = input.name;
if (name === "homestead") {
name = "mainnet";
}
return capitalize(name);
}
export function formatOrg(input: string, config: Config): string {
if (isAddress(input)) {
return ethers.utils.getAddress(input);