---
title: "Web3 Auth"
description: "Learn how to authenticate users with web3 wallets via the walt.id wallet API."
stack: "Community Stack (open source) — version 0.21.0"
stack_version: "0.21.0"
stack_comparison: https://docs.walt.id/community-vs-enterprise.md
canonical_url: https://docs.walt.id/community-stack/wallet/authentication/web3-auth
generated: 2026-07-20
---
# Web3 Authentication

The wallet-api lets users create and secure their account by leveraging web3 authentication.
Based on the latest standards, like [Login With Ethereum](https://eips.ethereum.org/EIPS/eip-4361).

### Supported Blockchains

- Ethereum

### Enabling Web3 Authentication feature in the wallet-api

To enable the web3 authentication feature in the wallet-api, you need to set the following features in the
`_features.conf` file :

```bash
enabledFeatures = [
  # external-signature-endpoints,
  # trusted-ca,
  # entra,
  ktor-authnz,
  # dev-mode
  # ...
  ]
  disabledFeatures = [
   auth   # legacy auth
]
```

### Configure the auth flow in `ktor-authnz.conf` file :

```bash
# Configure the Auth Flow (refer to: waltid-ktor-authnz)
authFlow = {
    method: web3
    expiration: "7d" # optional: Set expiration time for login tokens, e.g. a week
    ok: true # Auth flow ends successfuly with this step
```

## Authentication Flow

1. **Client Requests Nonce**
    - Client calls GET `/web3/nonce`
    - Server generates a random nonce and returns it as a JWT

2. **Client Signs Message**
    - Client uses their Ethereum wallet to sign the nonce
    - Message is formatted according to EIP-191 standard

3. **Client Submits Signature**
    - Client sends the signed message , the challenge and public key to POST `/web3/signed`
    - Server verifies the signature and authenticates the user

4. **Server Authentication**
    - Server recovers the public key from the signature
    - Verifies the recovered address matches the provided address
    - Creates or retrieves user account
    - Issues session token

## Generate a new nonce for web3 authentication

To login with a web3 wallet, you need to generate a nonce first. The nonce is a random string that is used to sign a
message and verify the signature.:

**Option: CURL**

[API Reference](https://wallet.demo.walt.id/swagger/index.html#/Authentication/get_wallet_api_auth_account_web3_nonce)

```bash
curl -X 'POST' \
  'http://0.0.0.0:7001/wallet-api/auth/account/web3/nonce' \
  -H 'accept: */*' 
```

**Example Response**

```bash
eyJhbGciOiJFZERTQSJ9.eyJub25jZSI6IjB4YjI1NzJhZWE2ODEyYmM4NjE2MDgyN2M3NmRmMjA3ZWVlNWNjMGVjNzQ4MmRlZjFhMmYxMTFiZTYxZGIzNjI3NyIsImV4cCI6MTczNzA2MjAyMH0.bQYGos3ZYA0POd5Dibvg7-NDZldVyReIW_0BsdDjVDpu0Tz1DJR9ZTpAuQlanC5hPgLB1yRua9_FPJ-0lokZCw
```

## Login

**Option: CURL**

[API Reference](https://wallet.demo.walt.id/swagger/index.html#/Authentication/post_wallet_api_auth_account_web3_signed)

```bash
curl -X 'POST' \
 'http://0.0.0.0:7001/wallet-api/auth/account/web3/signed' \
  -H 'accept: */*' \
  -H 'Content-Type: application/json' \
  -d '{
  "challenge": "eyJhbGciOiJFZERTQSJ9.eyJub25jZSI6IjB4YTgzNzI1M2U3ZDdmNjhkMGI5ODM2ZWMzNjlkZWE0MmMyYTFmMDg0ZWU3NDhjYTM0YTc4YTI2OTY4YTJiY2Q1NiIsImV4cCI6MTczNzA2MjE5OX0.DJAb5AgZO-Qgxe7nTkkt7qVWlM_bhQcpM7ZkD9HSqIQ81DAIm-OpOjv0Y56R6lmOVy82sVpHg4g7RUofTzieCg",
  "signed": "0x132463eab627a8ba10f0fc87871b48cb193ada7cab01ff68ed3627ab5b7268c64d3fe7172f58634ecb1412ff0084c70611dbe30c0cdc99528e2e06437a4056ae1c",
  "publicKey": "0xec57a39eb7e46728c143f8c1a0eb6d0fb77c814d"
}'
```

**Body Parameters**

```json
{
  "challenge": "string",
  "signed": "string",
  "publicKey": "string"
}
```

- `challenge`: _String_ - The nonce generated in the previous step.
- `signed`: _String_ - The signed message by the user.
- `publicKey`: _String_ - The public key of the user's wallet.

**Example Response**
<br />
Now a session is automatically created for web3 authentication. For Bearer Token Authentication, the `token`
returned
must be provided in the header for each request that needs authentication. Refer to
the [overview section](https://docs.walt.id/community-stack/wallet/authentication/overview.md#cookie-based-authentication) for more details.

```json
{
  "session_id": "0211b04c-cb5b-4b56-8a49-eaa63b4fdfe8",
  "status": "OK",
  "token": "eyJhbGciOiJFZERTQSJ9.eyJzdWIiOiI1MmIyZDQ2Zi0wNzQ0LTQ1YTgtOTIwNS1jZjdjYTMyODhkMzEiLCJzZXNzaW9uIjoiMDIxMWIwNGMtY2I1Yi00YjU2LThhNDktZWFhNjNiNGZkZmU4IiwiZXhwIjoxNzM3NjY2ODkxfQ.34-eydmcP7Vc8GJTsvqm8ofEnp2Ch_ZaZJHqYJO8edeBBvAoLB06YtWCLz2eDbLAxPyBkQwJOtJ6DPv0j1b3Cg",
  "expiration": "2025-01-23T21:14:51.542977200Z"
}
```
