> For the complete documentation index, see [llms.txt](/llms.txt).

# Sign in with Ethereum

Set up [Sign-In with Ethereum (SIWE)](https://docs.siwe.xyz/) to let users sign in to your dapp by authenticating with their MetaMask wallet.

MetaMask supports the SIWE standard message format as specified in [ERC-4361](https://eips.ethereum.org/EIPS/eip-4361). When your dapp prompts a user to sign a message that follows the SIWE format, MetaMask parses the message and gives the user a friendly interface prompting them to sign in to your dapp:

![Sign-in with Ethereum request](/assets/images/siwe-4c764ff564dac828ab4f91bf72d9b199.png)

## Domain binding[​](#domain-binding "Direct link to Domain binding")

MetaMask supports domain binding with SIWE to help prevent phishing attacks. When a site asks a user to sign a SIWE message, but the domain in the message doesn't match the site the user is on, MetaMask displays a warning in the sign-in interface. The user must explicitly select to proceed, accepting the risk of a phishing attack.

important

MetaMask displays a prominent warning for mismatched domains, but does **not** block users from bypassing the warning and accepting the sign-in request. This avoids breaking existing dapps that may have use cases for mismatched domains.

![MetaMask Sign-In with Ethereum domain mismatch warning](/assets/images/siwe-bad-domain-dcb08bee1f9104bfe4a0594136758f33.png)

![MetaMask Sign-In with Ethereum domain mismatch detailed warning popup](/assets/images/siwe-bad-domain-2-f52261a93ea9864d873f0a82b60bd2be.png)

## Example[​](#example "Direct link to Example")

The following is an example of setting up SIWE with MetaMask using [personal_sign](/metamask-connect/evm/reference/json-rpc-api/personal%5Fsign/):

index.js

```
import { createEVMClient } from '@metamask/connect-evm'

const evmClient = await createEVMClient({
  dapp: {
    name: 'MetaMask Connect EVM Example',
    url: window.location.href,
    iconUrl: 'https://mydapp.com/icon.png', // Optional
  },
  api: {
    supportedNetworks: {
      '0x1': 'https://mainnet.infura.io/v3/YOUR_INFURA_API_KEY',
      '0xaa36a7': 'https://sepolia.infura.io/v3/YOUR_INFURA_API_KEY',
    },
  },
})
const provider = evmClient.getProvider()

let accounts = []

const siweSign = async siweMessage => {
  try {
    const from = accounts[0]
    const msg = `0x${Buffer.from(siweMessage, 'utf8').toString('hex')}`
    const sign = await provider.request({
      method: 'personal_sign',
      params: [msg, from],
    })
    siweResult.innerHTML = sign
  } catch (err) {
    console.error(err)
    siweResult.innerHTML = `Error: ${err.message}`
  }
}

siwe.onclick = async () => {
  const result = await evmClient.connect()
  accounts = result.accounts
  const domain = window.location.host
  const from = accounts[0]
  const siweMessage = `${domain} wants you to sign in with your Ethereum account:\n${from}\n\nI accept the MetaMask Terms of Service: https://community.metamask.io/tos\n\nURI: https://${domain}\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z`
  siweSign(siweMessage)
}

```

The following HTML displays the SIWE button:

index.html

```
<h4>Sign-In with Ethereum</h4>
<button type="button" id="siwe">Sign-In with Ethereum</button>
<p class="alert">Result:<span id="siweResult"></span></p>

```

See the [live example](https://metamask.github.io/test-dapp/#siwe) and [test dapp source code](https://github.com/MetaMask/test-dapp) for more information.

## Next steps[​](#next-steps "Direct link to Next steps")

- [Sign data](/metamask-connect/evm/guides/sign-data/) with `personal_sign` and `eth_signTypedData_v4`.
- [Manage user accounts.](/metamask-connect/evm/guides/manage-user-accounts/)
- See [Ethereum provider API events and methods](/metamask-connect/evm/reference/provider-api/).
