Sign In With Ethereum
Web3Modal SDK provides a simple solution for integrating with "Sign In With Ethereum" (SIWE), a new form of authentication that enables users to control their digital identity with their Ethereum account. SIWE is a standard also known as EIP-4361.
One-Click Authβ
One-Click Auth represents a key advancement within WalletConnect v2, streamlining the user authentication process in Web3Modal by enabling them to seamlessly connect with a wallet and sign a SIWE message with just one click.
Connecting a wallet, proving control of an address with an off-chain signature, authorizing specific actions. These are the kinds of authorizations that can be encoded as "ReCaps". ReCaps are permissions for a specific website or dapp that can be compactly encoded as a long string in the message you sign and translated by any wallet into a straight-forward one-sentence summary. WalletConnect uses permissions expressed as ReCaps to enable a One-Click Authentication.
Installationβ
- One-Click Auth
- Legacy
- npm
- Yarn
- Bun
- pnpm
npm i @web3modal/siwe
yarn add @web3modal/siwe
bun a @web3modal/siwe
pnpm add @web3modal/siwe
For a better UX we recommend using One-Click Auth.
Install the Web3Modal SIWE package, additionally we also recommend installing siwe which will abstract a lot of the required logic.
- npm
- Yarn
- Bun
- pnpm
npm i @web3modal/siwe siwe
yarn add @web3modal/siwe siwe
bun a @web3modal/siwe siwe
pnpm add @web3modal/siwe siwe
Configure your SIWE Clientβ
- One-Click Auth
- Legacy
import { SiweMessage } from 'siwe'
import { createSIWEConfig } from '@web3modal/siwe'
import type { SIWECreateMessageArgs, SIWEVerifyMessageArgs, formatMessage } from '@web3modal/siwe'
function getMessageParams(){
return {
domain: window.location.host,
uri: window.location.origin,
chains: [1, 2020],
statement: 'Please sign with your account'
}
}
/* Function that returns the user's session */
async function getSession(){
const session = await getSession()
if (!session) throw new Error('Failed to get session!')
const { address, chainId } = session
return { address, chainId }
}
/* Use your SIWE server to verify if the message and the signature are valid */
async function verifyMessage({ message, signature }: SIWEVerifyMessageArgs){
try {
const isValid = await validateMessage({ message, signature })
return isValid
} catch (error) {
return false
}
},
/* Create a SIWE configuration object */
const siweConfig = createSIWEConfig({
getMessageParams,
createMessage: ({ address, ...args }: SIWECreateMessageArgs) => formatMessage(args, address),
getNonce,
getSession,
verifyMessage,
signOut
})
verifySignature
β
Verify a SIWE signature.
import { verifySignature } from '@web3modal/siwe'
const isValid = await verifySignature({ address, message, signature, chainId, projectId })
getChainIdFromMessage
β
Get the chain ID from the SIWE message.
import { getChainIdFromMessage } from '@web3modal/siwe'
const chainId = getChainIdFromMessage(message)
getAddressFromMessage
β
Get the address from the SIWE message.
import { getAddressFromMessage } from '@web3modal/siwe'
const address = getAddressFromMessage(message)
With help of the siwe package we will create the required configuration for Web3Modal.
The nonce and verification process will be implemented in your backend. Read more.
import { SiweMessage } from 'siwe'
import { createSIWEConfig } from '@web3modal/siwe'
import type { SIWECreateMessageArgs, SIWEVerifyMessageArgs } from '@web3modal/siwe'
/* Function that creates a SIWE message */
function createMessage({ nonce, address, chainId }: SIWECreateMessageArgs){
const message = new SiweMessage({
version: '1',
domain: window.location.host,
uri: window.location.origin,
address,
chainId,
nonce,
statement: 'Sign in With Ethereum.'
})
return message.prepareMessage()
}
/* Function that returns the user's session */
async function getSession(){
//...
}
/* Use your SIWE server to verify if the message and the signature are valid */
async function verifyMessage({ message, signature }: SIWEVerifyMessageArgs){
try {
const isValid = await validateMessage({ message, signature })
return isValid
} catch (error) {
return false
}
},
/* Create a SIWE configuration object */
const siweConfig = createSIWEConfig({
createMessage,
getNonce,
getSession,
verifyMessage,
signOut
})
Initialize Web3Modal with your siweConfig
β
createWeb3Modal({
//..
siweConfig
})
SIWE Config Parametersβ
- One-Click Auth
- Legacy
getMessageParams () => Promise<{ domain: string, uri: string, chains: number[], statement: string }>
β
Parameters to create the SIWE message internally.
getNonce () => Promise<string>
β
The getNonce method functions as a safeguard against spoofing, akin to a CSRF token. The siwe package provides a generateNonce() helper, or you can utilize an existing CSRF token from your backend if available.
createMessage (args: SIWECreateMessageArgs) => string
β
The official siwe package offers a straightforward method for generating an EIP-4361-compatible message, which can subsequently be authenticated using the same package. The nonce parameter is derived from your getNonce endpoint, while the address and chainId variables are sourced from the presently connected wallet.
verifyMessage (args: SIWEVerifyMessageArgs) => Promise<boolean>
β
The function to ensure the message is valid, has not been tampered with, and has been appropriately signed by the wallet address.
getSession () => Promise<SIWESession | null>
β
The backend session should store the associated address and chainId and return it via the getSession
method.
signOut () => Promise<boolean>
β
The users session can be destroyed calling signOut
.
onSignIn (session?: SIWESession) => void
β
Callback when user signs in (Optional).
onSignOut () => void
β
Callback when user signs out (Optional).
signOutOnDisconnect boolean
β
- defaults to
true
Whether or not to sign out when the user disconnects their wallet (Optional).
getNonce () => Promise<string>
β
The getNonce method functions as a safeguard against spoofing, akin to a CSRF token. The siwe package provides a generateNonce() helper, or you can utilize an existing CSRF token from your backend if available.
createMessage (args: SIWECreateMessageArgs) => string
β
The official siwe package offers a straightforward method for generating an EIP-4361-compatible message, which can subsequently be authenticated using the same package. The nonce parameter is derived from your getNonce endpoint, while the address and chainId variables are sourced from the presently connected wallet.
verifyMessage (args: SIWEVerifyMessageArgs) => Promise<boolean>
β
The verifyMessage
method should lean on the siwe package's new
SiweMessage(message).validate(signature)
to ensure the message is valid, has not been tampered with, and has been appropriately signed by the wallet address.
getSession () => Promise<SIWESession | null>
β
The backend session should store the associated address and chainId and return it via the getSession
method.
signOut () => Promise<boolean>
β
The users session can be destroyed calling signOut
.
onSignIn (session?: SIWESession) => void
β
Callback when user signs in (Optional).
onSignOut () => void
β
Callback when user signs out (Optional).
signOutOnDisconnect boolean
β
- defaults to
true
Whether or not to sign out when the user disconnects their wallet (Optional).
Was this helpful?