Kevo Docs

EVM Wallet Authentication

Let users sign in with their existing EVM wallets (MetaMask, Rabby, Coinbase Wallet, and any EIP-1193 compatible extension).

How it works

EVM wallet auth uses the standard challenge-sign flow (SIWE-style):

  1. Kevo generates a nonce tied to the wallet address and project.
  2. The user signs the challenge message with their wallet (personal_sign).
  3. Kevo verifies the ECDSA signature and issues a session.

Pre-built Modal

If the project has evm in enabledChains, the modal automatically shows EVM wallet options:

MetaMask

window.ethereum?.isMetaMask

Rabby

window.rabby

Coinbase Wallet

window.ethereum?.isCoinbaseWallet

Bybit Wallet

window.bybitWallet

OKX Wallet

window.okxwallet

Trust Wallet

window.trustwallet

Programmatic Sign-in

typescript
import { useKevo } from '@kevo-ws/sdk/react'

function ConnectMetaMask() {
  const { client } = useKevo()

  const connect = async () => {
    const provider = window.ethereum
    if (!provider) {
      alert('Please install MetaMask')
      return
    }
    await client.loginWithWallet({ provider })
    // session is now active
  }

  return <button onClick={connect}>Connect MetaMask</button>
}

API Flow

1. Get nonce

http
GET /v1/auth/wallet/nonce
  ?address=0xAbCd...1234
  &projectId=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

# Response:
{
  "message": "Sign in to Kevo\n\nWallet: 0xAbCd...\nNonce: abc123\nIssued At: 2026-04-02T12:00:00.000Z",
  "nonce": "abc123"
}

2. Verify signature

http
POST /v1/auth/wallet/verify
Content-Type: application/json

{
  "address": "0xAbCd...1234",
  "message": "Sign in to Kevo\n\n...",
  "signature": "0xdeadbeef...",
  "projectId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

# Response:
{
  "accessToken": "eyJ...",
  "expiresIn": 900,
  "address": "0xAbCd...1234"
}
# Plus: Set-Cookie: kevo_refresh_token=...
External EVM wallets are not Kevo-managed embedded wallets. They are linked as an auth method only. To sign transactions through Kevo's embedded wallet flow, the user needs a Kevo-managed wallet, see the EVM Wallets page.
Rate limits: 10 nonce requests per address per minute, 5 verify attempts per address per minute.