Diffusal

Authentication

Sign in with Ethereum (SIWE) — Better Auth session

Diffusal uses Better Auth with the SIWE (Sign-In with Ethereum) plugin for session management. Authentication is wallet-only and uses Better Auth's native two-step SIWE flow, which converges on a bearer token or session cookie used by every authenticated request.

For traders using the web app, authentication is handled automatically. For API integrators, market makers, and bot operators, the SIWE flow described below is the only programmatic option.

How It Works

                    SIWE (wallet signature)


            POST /api/auth/siwe/nonce
          with walletAddress + chainId


            POST /api/auth/siwe/verify
          with message + signature


                   Better Auth Session Token
                  (Authorization: Bearer <token>
                   or better-auth.session_token cookie)


                   Protected API Endpoints
             /api/account/* /api/mm/* /api/portfolio/*

Wallet Sign-In (SIWE)

SIWE proves wallet ownership without a password and is the only sign-in flow exposed by the API.

Step 1: Request a nonce

curl -X POST https://api.testnet.diffusal.xyz/api/auth/siwe/nonce \
  -H 'Content-Type: application/json' \
  -d '{"walletAddress": "0xYourAddress", "chainId": 10143}'

Response:

{ "nonce": "a3f2c91d..." }

Nonces expire after 5 minutes. Complete the sign-in flow before the TTL elapses.

Step 2: Build and sign the SIWE message

Construct a EIP-4361 SIWE message with the nonce from Step 1, then sign it with your wallet.

api.testnet.diffusal.xyz wants you to sign in with your Ethereum account:
0xYourAddress

Sign in to Diffusal

URI: https://api.testnet.diffusal.xyz
Version: 1
Chain ID: 10143
Nonce: a3f2c91d...
Issued At: 2026-01-01T00:00:00.000Z

Step 3: Verify signature and receive session token

curl -X POST https://api.testnet.diffusal.xyz/api/auth/siwe/verify \
  -H 'Content-Type: application/json' \
  -d '{"message": "<SIWE_MESSAGE>", "signature": "0x...", "walletAddress": "0xYourAddress", "chainId": 10143}'

Response:

{
  "token": "3e9a7c12-4d5f-...",
  "success": true,
  "user": {
    "id": "user_123",
    "walletAddress": "0xYourAddress",
    "chainId": 10143
  }
}

Store this token — you will attach it to every authenticated request.


Using Your Session Token

After authentication, attach the token to protected API calls using either method:

Bearer header (recommended for programmatic use):

curl https://api.testnet.diffusal.xyz/api/account/me \
  -H 'Authorization: Bearer <token>'

Session cookie (automatically set in browser flows):

Cookie: better-auth.session_token=<token>

Session TTL: 7 days. After expiry, re-authenticate to obtain a new token.


Protected Endpoints

Once authenticated, you have access to:

Endpoint GroupDescription
/api/account/*Account info, profile
/api/mm/*Market maker orders and quotes
/api/portfolio/*Portfolio management
/api/strategies/*Multi-leg strategy execution

Common Auth Errors

HTTP StatusMessageCause
400Invalid SIWE message: no nonceSIWE message is malformed or missing the nonce field
400Domain mismatch: expected api.testnet.diffusal.xyzThe domain in your SIWE message does not match the API host
401Invalid or expired nonceNonce was already used, or more than 5 minutes elapsed
401Invalid SIWE signatureSignature does not match the signing address
401Invalid or expired sessionBearer token not found in session store or session has expired

Security Model

  • Nonce-based replay protection — Each nonce is single-use and expires in 5 minutes
  • Signed ownership proof via SIWE — The signature cryptographically binds the Ethereum address to the session
  • Session validation on protected endpoints — Every request to protected routes validates the session token before execution

See Also

On this page