Authentication

Auth across the platform — wallet JWT (Dynamic.xyz), scoped API keys, MCP OAuth, session lifetimes.

What this is

TRUE has three auth flows for three different surfaces: wallet-based JWT for end users, scoped API keys for backend integrations, and MCP OAuth for multi-user agentic clients. Pick the one that matches your client; never mix them.

Wallet-based JWT (Dynamic.xyz)

End users authenticate by signing a one-time message with their Solana wallet. The signature is verified by Dynamic.xyz and exchanged for a short-lived JWT bound to the wallet address. The JWT carries the user’s wallet pubkey, locale preference, and feature scopes; it does not carry any custodial signing power.

  • JWT lifetime: 1 hour. Refresh runs silently against an opaque refresh token stored in HttpOnly cookies.
  • Refresh lifetime: 30 days. After 30 days of inactivity the user re-signs.
  • Revocation: instant via the dashboard or POST /api/v1/auth/revoke.

Scoped API keys

Backend integrations use static keys with explicit scopes:

  • tp_live_… — production keys.
  • tp_test_… — sandbox keys, no real funds, no real points.

Scopes are granted at issuance time and cannot be expanded later — issue a new key with the wider scope and revoke the old one. Available scopes:

ScopeAllows
read:priceTRUE Quotes reads, market data
read:catalystsCatalyst feed reads
read:userAuthenticated user’s profile, watchlist, points
subscribe:webhooksWebhook registration & delivery
read:mcpMCP read-only tool calls
execute:mcpMCP execution tools (gated, partner-tier)

MCP OAuth

Multi-user MCP clients (AI assistants, research workspaces) use the OAuth 2.1 + PKCE flow. The grant binds the MCP session to a specific TRUE user wallet so each tool call inherits that user’s scopes, watchlist, and points balance.

GET https://app.truefinance.ai/api/v1/oauth/authorize
POST https://app.truefinance.ai/api/v1/oauth/token
# Authorization URL
https://app.truefinance.ai/api/v1/oauth/authorize
  ?response_type=code
  &client_id=cli_01JX...
  &redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
  &code_challenge=...
  &code_challenge_method=S256
  &scope=read:price%20read:user%20read:mcp
  &state=opaque

PKCE is mandatory for public clients. Refresh tokens are rotated on every use.

Key handling rules
  • Never commit keys to repos. Even private repos. Use environment variables or a secrets manager; rotate on a known cadence.
  • Never put keys in client-side bundles. Proxy through your backend.
  • Use the smallest viable scope set per integration. A key without execute:mcp cannot trigger execution if it leaks.
  • On compromise: revoke immediately, then rotate downstream consumers, then audit the key’s usage history.
  • Phishing pattern: any “key verification” link asking you to paste a key is a phishing attempt. TRUE never asks for raw key material.
For Developers

When to use which

  • Wallet JWT — your client renders the TRUE app or a thin embed where the user holds the wallet.
  • API key — your backend talks to TRUE on behalf of itself (data ingestion, webhooks, monitoring).
  • OAuth — your AI assistant talks to TRUE on behalf of an end user via MCP.

Code samples

// TypeScript — using a scoped API key
const r = await fetch('https://quotes.truefinance.ai/v1/price/SOL', {
  headers: { Authorization: `Bearer ${process.env.TRUE_API_KEY}` },
});
# Python
import os, httpx

r = httpx.get(
    "https://quotes.truefinance.ai/v1/price/SOL",
    headers={"Authorization": f"Bearer {os.environ['TRUE_API_KEY']}"},
    timeout=10.0,
)
r.raise_for_status()
// Rust (reqwest)
let token = std::env::var("TRUE_API_KEY")?;
let resp = reqwest::Client::new()
    .get("https://quotes.truefinance.ai/v1/price/SOL")
    .bearer_auth(token)
    .send().await?
    .error_for_status()?;

Rotation

Quarterly is the recommended cadence. The dashboard supports overlap windows: provision a new key, deploy to consumers, revoke the old key after the rollout completes.

Safety, limits, failure modes

  • Key compromise. Revoke first; then rotate; then audit. The dashboard shows last-used IP and tool histogram per key.
  • Token replay. JWTs include a jti claim and are bound to the wallet pubkey; replays from a different IP/origin trigger a soft revoke.
  • Clock skew. JWT validation tolerates ±60s of clock skew between issuer and consumer.
  • OAuth state mismatch. A returned state value that doesn’t match the request is rejected; treat any mismatch as a CSRF attempt.

See also

  • MCP — the surface OAuth grants are scoped against.
  • Rate Limits — per-key and per-user quotas.
  • Safety Overview — broader key and wallet hygiene.
Last updated: