Our Crypto wallets product unlocks Web3 authentication in your app in four easy steps. For this guide we'll walk through integrating MetaMask, but you may integrate any Ethereum based wallet with Stytch, we'll talk about this more later in the guide.
If you get stuck while working through this guide, feel free to ask questions in our forum, via support@stytch.com, or in our Slack community.
Step 1: Get Ethereum address
To start, we need the user's Ethereum address we want to authenticate with. We can use the following code snippet to fetch the user's MetaMask Ethereum address from the browser. You'll have to check if window.ethereum is defined – if it isn't, the user doesn't have MetaMask installed.
const [address] = await window.ethereum.request({ method: 'eth_requestAccounts' });
Step 2: Start Ethereum authentication
Using the Ethereum address, make a request to /v1/crypto_wallets/authenticate/start. If you want to add this Ethereum address to an existing user, pass in that user's user_id. If the Ethereum address doesn't belong to a user yet, leaving out a user_id will create a new user automatically.
You can optionally use the Sign in With Ethereum (SIWE) protocol by passing in the siwe_params parameter. SIWE is recommended for Ethereum crypto wallet flows because it will automatically warn the end user if the domain passed in the message does not match the domain of the site making the signing request to the crypto wallet.
The only required parameters for SIWE are domain and uri. You can read more about each individual parameter in our docs, and you can also check out the full SIWE spec.
curl --request POST \
--url https://test.stytch.com/v1/crypto_wallets/authenticate/start \
-u 'PROJECT_ID:SECRET' \
-H 'Content-Type: application/json' \
-d '{
"crypto_wallet_type": "ethereum",
"crypto_wallet_address": "0x6df2dB4Fb3DA35d241901Bd53367770BF03123f1",
"user_id": "user-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6", // optional
"siwe_params": { "domain": "example.com", "uri": "https://example.com" } // optional
}'
Step 3: Signing the message
Using the challenge field from the /v1/crypto_wallets/authenticate/start response, request the user to sign the message. The user will see a MetaMask popup asking to sign a message with the content from the challenge. You'll also have to gracefully handle the situation where a user chooses to reject the message.
// get challenge from authenticate/start call
const signature = await window.ethereum.request({"method": "personal_sign", "params": [challenge, address]})
Step 4: Finish Ethereum authentication
Using the signature from the signMessage call described in the last step, make a request to /v1/crypto_wallets/authenticate. Optionally, you may provide an existing session_token to reuse an existing session, and/or provide a session_duration_minutes value to set the lifetime of the session.
Stytch will perform validation on the address, challenge, and signature and return a 400 if there are any issues. If the authentication is successful, we'll return a 200.
curl --request POST \
--url https://test.stytch.com/v1/crypto_wallets/authenticate/start \
-u 'PROJECT_ID:SECRET' \
-H 'Content-Type: application/json' \
-d '{
"crypto_wallet_type": "ethereum",
"crypto_wallet_address": "0x6df2dB4Fb3DA35d241901Bd53367770BF03123f1",
"signature": "0x0c4f82edc3c818b6beff4b89e0682994e5878074609903cecdfb843241728be32f75949e2fbae63dcccdef97c0e3789a26441f7e11456cc1f2ef79b3a436010f1b"
}'
Step 5: You're Done!
You just finished all the critical components to authenticate your users with a MetaMask wallet! Have any feedback after having integrated Ethereum with your app? Get in touch with us and tell us what you think in our forum, support@stytch.com, or in our Slack community.