6

When a user goes to a crypto-related website (like Pancakeswap for example), the website asks the user to connect their wallet (eg Metamask, Binance Chain Wallet). I have several questions:

  1. What exactly happens when the user connects their wallet? Is there a transaction that records this "connection" on the blockchain, or is the fact that the wallet is connected to this site somehow stored locally on the user's machine? How does the website know that the user agreed to connect their wallet at some point in the past? I suspect this has something to do with web3.js somehow being injected, but I'm not sure.

  2. If I run a site locally (on localhost), is it safe to connect my wallet to localhost? Or does this create security risks?

5 Answers 5

11

Connecting your wallet doesn't really do much: it doesn't send any transactions. About all it does it gives your wallet's public address to the website and the possibility for the website to request actions from the wallet - actions which you, as a user, need to accept manually.

In theory, everything would be smoother and more user friendly if your wallet automatically connected to a site whenever needed. But the connection is not automatic for security reasons: by auto-connecting (or even just by telling the site that you have a wallet) you would give too much information to the website. A malicious website might try to detect whether a user has a wallet, and if does, then the site could start various crypto scams / phishing attacks. If the website has no idea whether you even have a wallet (as is the case) unless you connect your wallet, the website has no idea whether it's worth it to even try some sort of nasty stuff.

So if you run code you are familiar with (or trust), you can safely connect your wallet locally. Also in general connecting your wallet to any website isn't a big security risk, but it's simply better to not connect unless you have a need for it.

3

Here is official answer: https://docs.metamask.io/guide/getting-started.html#connecting-to-metamask

Very sample: just allow website to read your wallet address

no transaction, no risk (like tell a website your email address, maybe only get some spam. in web3 world ,you may get some "spam coin")

3
  • This only says what happens on the client side. It doesn't really say what happens on the blockchain side. Thanks anyway.
    – Marc
    Commented Sep 12, 2022 at 17:56
  • @Marc there is noting happen in the chain. you can use hardhat run test chain, then add test chain to your matemask. try connect any web3 website. you can see nothing output when confirm connect.
    – Robin
    Commented Sep 13, 2022 at 12:54
  • you can read eip-1102 to get more info: eips.ethereum.org/EIPS/eip-1102
    – Robin
    Commented Sep 13, 2022 at 12:59
3

Just adding a bit more caution to the accepted answer:

As per Metamask, connecting your wallet allows the following:

| See address, account balance, activity and suggest transactions to approve

Metamask strongly recommends that you only connect with websites that you trust. (https://metamask.zendesk.com/hc/en-us/articles/4405506066331-User-guide-Dapps).

This is because there are scams in which a website's button may say that it's asking you only to connect, but in reality the prompt sent to Metamask is asking for more than just a wallet connection.

To be safe, it's best to read exactly what the Metamask/wallet prompt is asking for.

0

I connected my wallet to a scam sight and they collected my money, pls how can I secure that wallet? Or it has been corrupted. Do I need any strong security for the wallet or what could I do to secure this wallet from these scammers?

1
  • Delete that wallet and make another. If you have questions, open a question, this is a place for answers.
    – 0xSanson
    Commented Jun 23 at 10:13
0

According to cra-template-solidity, when MetaMask Extension is installed it monkey-patch window with ethereum object. If window.ethereum is undefined, there is no MetaMask extension installed.

import { makeAutoObservable, runInAction } from "mobx";

import { singleshot } from "react-declarative";
import { ethers } from 'ethers'

interface IWindowExtended extends Window {
    ethereum: any;
    web3: any;
}

const window = globalThis as unknown as IWindowExtended;

export class EthersService {

    private _provider: ethers.providers.Web3Provider = null as never;

    get isProviderConnected() {
        return !!this._provider;
    };

    get isMetamaskAvailable() {
        return !!window.ethereum;
    };

    get isAccountEnabled() {
        return !!window.ethereum?.selectedAddress;
    };

    get provider() {
        return this._provider;
    };

    constructor() {
        makeAutoObservable(this);
    };

    enable = async () => {
        await window.ethereum.request({ method: 'eth_requestAccounts' });
        this.registerWalletEvents();
    };

    getNetwork = async () => {
        const network = await this._provider.getNetwork();
        return network;
    };

    getAccount = async () => {
        const accounts = await this._provider.listAccounts();
        return accounts[0] || null;
    };

    getChainId = async () => {
        const { chainId } = await this.getNetwork();
        return chainId;
    };

    getSigner = () => {
        return this._provider.getSigner();
    };

    getCode = (address: string) => {
        return this._provider.getCode(address);
    };

    personalSign = async (message: string): Promise<string> => {
        const account = await this.getAccount();
        return await window.ethereum.request({
            params: [message, account],
            method: "personal_sign",
            from: account,
        });
    };

    addTestChain = (chainId: string | number = 1337) => {
        if (!String(chainId).includes('0x')) {
            chainId = `0x${chainId.toString(16)}`;
        }
        window.ethereum.request({
            method: "wallet_addEthereumChain",
            params: [{
                chainId,
                rpcUrls: ["http://localhost:8545"],
                chainName: "Local GETH",
                nativeCurrency: {
                    name: "GETH",
                    symbol: "GETH",
                    decimals: 18
                },
            }]
        });
    };

    validateSign = async (message: string, sign: string): Promise<string | null> => {
        try {
            return await window.ethereum.request({
                params: [message, sign],
                method: "personal_ecRecover",
            });
        } catch (e: unknown) {
            console.warn(e);
            return null;
        }
    };

    private registerWalletEvents = () => {
        window.ethereum.on('accountsChanged', () => {
            window.location.reload();
        });
        window.ethereum.on('chainChanged', () => {
            window.location.reload();
        });
    };

    prefetch = singleshot(async () => {
        console.log("EthersService prefetch started");
        try {
            if (window.ethereum) {
                console.log("EthersService prefetch eip-1102 detected");
                const provider = new ethers.providers.Web3Provider(window.ethereum);
                runInAction(() => this._provider = provider);
            }
            if (this.isAccountEnabled) {
                this.registerWalletEvents();
            }
        } catch (e) {
            console.warn('EthersService prefetch failed', e);
        }
    });

};

export default EthersService;

The window.ethereum object contains isMetaMask boolean property, selectedAddress string or null property, the request method. It implements EventEmitter, so you can listen for result of request method execution. There are several events you need to known:

/**
 * Switched to another account in metamask
 */
window.ethereum.on('accountsChanged', () => {
    window.location.reload();
});

/**
 * Switched to another network, like BNB or Ethereum Classic
 */
window.ethereum.on('chainChanged', () => {
    window.location.reload();
});

Before running await window.ethereum.request({ method: 'eth_requestAccounts' }) the window.ethereum object will not allow to execute any blockchain request. You can check if person is sign in by reading window.ethereum.selectedAddress property.

yarn create react-app --template cra-template-solidity .

# or 

npx create-react-app . --template=solidity

You can try it by yourself by executing the following command in shell

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.