Agent Authentication — EVM Wallet Signing & JWT Flow | DeFiMara

What Is Agent Authentication?

DeFiMara uses EVM wallet-based authentication. Instead of passwords or API keys, your agent signs a server-issued challenge with an Ethereum private key. The server verifies the signature and returns a JWT valid for 24 hours. No secrets stored server-side.

Authentication Flow

1. GET /auth/challenge — Request a one-time challenge string for your wallet address. 2. Sign the challenge with your EVM private key using personal_sign. 3. POST /auth/verify — Send address, challenge, and signature. Server returns a signed JWT. 4. Include Authorization: Bearer <token> in every /chat request.

Security Best Practices

Use a dedicated agent wallet — not your personal main wallet. Fund it with only the gas needed for operations. Use HTTPS in production. Rotate the key if it is ever exposed.

Supported Languages

Python (web3.py), Node.js (ethers.js), any language that can perform secp256k1 ECDSA signing.

Back to Blog
API
November 20255 min read

Agent Authentication

What Is Agent Auth?

Defimara uses EVM wallet-based authentication. Instead of passwords or API keys, your agent signs a server-issued challenge with an Ethereum private key. The server verifies the signature and returns a JWT valid for 24 hours. No secrets stored server-side.

Use a dedicated agent wallet - not your personal wallet. Fund it with only the gas needed for operations.

• How It Works

1
GET /auth/challenge
Request a one-time challenge string tied to your wallet address.
2
Sign the challenge
Sign the challenge with your EVM private key using eth_sign (personal_sign).
3
POST /auth/verify
Send {address, challenge, signature}. Server returns a signed JWT.
4
Include JWT in requests
Add Authorization: Bearer <token> to every /chat or /stream request.

• Requirements

An EVM private key (secp256k1) - any Ethereum-compatible wallet
web3.py (Python) or ethers.js (Node.js) for signing
JWT token is valid for 24 hours, then re-authenticate
HTTPS strongly recommended in production deployments

• Code Example

Python
from web3 import Web3
import requests

KEY = "0xYourPrivateKey"
BASE = "http://localhost:8000"

w3 = Web3()
account = w3.eth.account.from_key(KEY)

# 1. Get challenge
challenge = requests.get(
    f"{BASE}/auth/challenge",
    params={"address": account.address}
).json()["challenge"]

# 2. Sign
sig = account.sign_message(
    encode_defunct(text=challenge)
).signature.hex()

# 3. Verify -> get JWT
token = requests.post(f"{BASE}/auth/verify", json={
    "address": account.address,
    "challenge": challenge,
    "signature": sig,
}).json()["access_token"]

Share this article