Skip to main content

Auth Flow

SuperVaults uses Dynamic.xyz for wallet connection and JWT issuance.
1

Connect Wallet

Open curators.superform.xyz and click Connect Wallet. Dynamic.xyz presents a wallet selection modal supporting MetaMask, Rabby, WalletConnect, and others.
2

Sign Auth Message

Your wallet signs a non-transactional message. Dynamic.xyz verifies the signature and issues a JWT tied to your wallet address.
3

JWT Stored in Browser

The Curator App stores auth state in localStorage:
  • curator_jwt — the Bearer token used on all API requests
  • curator_address — connected wallet address
  • curator_is_manager — boolean flag
  • curator_vaults — array of vault addresses you manage
4

Auth Verified

The app calls GET /api/v1/auth/me on load to fetch your vault roles and confirm the JWT is valid.

Primary Auth Endpoint

GET /api/v1/auth/me
Authorization: Bearer <jwt>
Response:
{
  "wallet_address": "0xabc...",
  "is_manager": true,
  "vaults": [
    {
      "vault_address": "0xdef...",
      "chain_id": 8453,
      "role": "primary_manager"
    }
  ]
}
GET /api/v1/auth/me is the primary authentication path. It returns the current user with all assigned vault roles. Use this endpoint when building integrations.

JWT Verification Endpoint

GET /api/v1/auth/verify
Authorization: Bearer <jwt>
Returns:
{
  "verified": true,
  "walletAddress": "0xabc...",
  "isManager": true,
  "vaults": ["0xdef..."]
}

Token Lifecycle

  • JWTs expire after a session period defined by Dynamic.xyz
  • Any 401 Unauthorized from Erebor triggers automatic logout via authService.handleAutoLogout()
  • Reconnecting your wallet re-issues a fresh JWT

Public Endpoints (No Auth)

EndpointDescription
GET /api/v1/public/vaultsAll SuperVault deployments with TVL and APY
GET /api/v1/registry/token-assetsToken asset metadata

Programmatic Authentication

For automation scripts, generate a JWT without the browser:
  1. Sign an EIP-712 auth message with your wallet’s private key
  2. Submit the signature to Dynamic.xyz to receive a JWT
  3. Pass the JWT as Authorization: Bearer <jwt> on all requests
import requests

EREBOR_URL = "https://erebor.superform.xyz"
JWT = "<your-jwt>"

headers = {"Authorization": f"Bearer {JWT}"}

resp = requests.get(f"{EREBOR_URL}/api/v1/auth/me", headers=headers)
resp.raise_for_status()
user = resp.json()

print(f"Connected as: {user['wallet_address']}")
print(f"Manages {len(user['vaults'])} vault(s)")
Never hardcode JWTs in source code. Use environment variables (CURATOR_JWT) and rotate tokens regularly. JWTs grant full manager-level access to your vaults.