Wallet Authentication
KnowledgeFlowDB’s hosted experience is wallet-based, but the production flow is not “just send a wallet address”. The normal path is:
- Sign in with Privy
- Mint a bearer token from a wallet signature
- 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
| Step | Purpose | Result |
|---|---|---|
| Privy login | Establish user session and embedded wallet | Wallet ready in browser |
/auth/challenge + /auth/verify | Prove wallet ownership with EIP-712 typed data | Bearer token |
/api/v1/auth/derive-challenge + /api/v1/auth/derive-key | Derive user-controlled encryption session | x-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:
- Privy creates or restores the embedded wallet
- The docs app requests a KFDB auth challenge
- Your wallet signs the EIP-712 payload
- KFDB returns a bearer token
- The docs app requests a derive challenge
- Your wallet signs a second EIP-712 payload
- The browser computes
SHA-256(signatureBytes)to produce the derive key - KFDB stores only the HMAC/session metadata and returns a derive session id
- 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
502responses 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.