Skip to main content

Wallet Authentication

KnowledgeFlowDB’s hosted experience is wallet-based, but the production flow is not “just send a wallet address”. The normal path is:

  1. Sign in with Privy
  2. Mint a bearer token from a wallet signature
  3. Mint a sign-to-derive session so private data can be read and written with the user-controlled key

The interactive docs now follow that flow automatically when you sign in.

Production Flow

StepPurposeResult
Privy loginEstablish user session and embedded walletWallet ready in browser
/auth/challenge + /auth/verifyProve wallet ownership with EIP-712 typed dataBearer token
/api/v1/auth/derive-challenge + /api/v1/auth/derive-keyDerive user-controlled encryption sessionx-derive-session-id + x-derive-key

Interactive Docs Flow

On pages like KQL Syntax, you do not need to paste an endpoint, API key, or wallet address.

When you click Sign In:

  1. Privy creates or restores the embedded wallet
  2. The docs app requests a KFDB auth challenge
  3. Your wallet signs the EIP-712 payload
  4. KFDB returns a bearer token
  5. The docs app requests a derive challenge
  6. Your wallet signs a second EIP-712 payload
  7. The browser computes SHA-256(signatureBytes) to produce the derive key
  8. KFDB stores only the HMAC/session metadata and returns a derive session id
  9. Queries run with the correct headers automatically

The headers used by the docs app are:

Authorization: Bearer <token>
x-derive-session-id: <session_id>
x-derive-key: <64-char-hex-key>

Direct API Flow

If you are building your own client instead of using the hosted docs UI, use the direct KFDB API routes below.

1. Request a Wallet Challenge

curl 'https://api.knowledgedataflow.org/auth/challenge?chain_id=8453'

Response shape:

{
"challenge_id": "uuid",
"message": "Sign this typed data to authenticate...",
"issued_at": 1713052800,
"expires_at": 1713053100,
"typed_data": {
"types": {
"EIP712Domain": [
{ "name": "name", "type": "string" },
{ "name": "version", "type": "string" },
{ "name": "chainId", "type": "uint256" }
],
"AuthMessage": [
{ "name": "message", "type": "string" },
{ "name": "nonce", "type": "string" },
{ "name": "issuedAt", "type": "uint256" },
{ "name": "expiresAt", "type": "uint256" }
]
},
"primaryType": "AuthMessage",
"domain": {
"name": "KnowledgeFlowDB",
"version": "1",
"chainId": 8453
},
"message": {
"message": "Sign this typed data to authenticate...",
"nonce": "uuid",
"issuedAt": "1713052800",
"expiresAt": "1713053100"
}
}
}

2. Sign the EIP-712 Typed Data

Use your wallet’s typed-data signing API. Do not use personal_sign here.

3. Exchange the Signature for a Bearer Token

curl -X POST 'https://api.knowledgedataflow.org/auth/verify' \
-H 'Content-Type: application/json' \
-d '{
"challenge_id": "uuid",
"signature": "0x...",
"address": "0xYOUR_WALLET_ADDRESS"
}'

Response:

{
"token": "eyJhbGciOi...",
"address": "0xYOUR_WALLET_ADDRESS",
"expires_at": 1713139200
}

4. Request a Sign-to-Derive Challenge

curl -X POST 'https://api.knowledgedataflow.org/api/v1/auth/derive-challenge'

5. Sign the Derive Payload and Register the Session

After signing the derive typed data, compute the derive key locally:

derive_key = SHA-256(signature_bytes)

Then register the session:

curl -X POST 'https://api.knowledgedataflow.org/api/v1/auth/derive-key' \
-H 'Content-Type: application/json' \
-d '{
"challenge_id": "uuid",
"signature": "0x...",
"address": "0xYOUR_WALLET_ADDRESS"
}'

Response:

{
"wallet_address": "0xYOUR_WALLET_ADDRESS",
"session_id": "uuid",
"expires_at": 1744585600
}

Using the Authenticated Session

For normal authenticated API requests:

curl -X POST 'https://api.knowledgedataflow.org/api/v1/query' \
-H 'Authorization: Bearer <token>' \
-H 'x-derive-session-id: <session_id>' \
-H 'x-derive-key: <64-char-hex-key>' \
-H 'Content-Type: application/json' \
-d '{"query":"SHOW LABELS"}'

The derive headers are especially important for private, wallet-scoped data and writes that require the user key.

Advanced / Programmatic Variants

Bearer token only

Use this for workflows that only need authenticated API access and do not need a browser-driven interactive session:

Authorization: Bearer <token>

API keys

API keys still exist for programmatic access and service integrations. They are an advanced path, not the primary hosted-service onboarding flow.

Legacy X-Wallet-Address

Some endpoints and older tooling still accept X-Wallet-Address. Treat that as a compatibility path or internal/debug fallback, not the recommended user flow.

Notes

  • The direct auth routes above are based on the current KFDB backend router.
  • During this audit, the public auth host returned transient 502 responses when probed on April 14, 2026, so the docs now avoid over-promising “copy/paste this exact curl and it will work right now” for interactive usage. The docs-site experience itself uses the same flow internally.