# API Reference URL: /docs/api Complete REST API documentation for TokenPass Server TokenPass Server exposes a REST API on `http://localhost:21000`. All endpoints are prefixed with `/api/` and accept/return JSON. TokenPass uses a two-step authentication: first unlock the wallet with `/api/login`, then get access tokens with `/api/auth`. ## Quick Start ### Register a Wallet (First Time Only) ```bash curl -X POST http://localhost:21000/api/register \ -H "Content-Type: application/json" \ -d '{ "password": "my-secure-password", "displayName": "Alice" }' ``` ### Login (Unlock Wallet) ```bash curl -X POST http://localhost:21000/api/login \ -H "Content-Type: application/json" \ -d '{"password": "my-secure-password"}' ``` ### Get an Access Token ```bash curl -X POST http://localhost:21000/api/auth \ -H "Content-Type: application/json" \ -d '{ "password": "my-secure-password", "host": "example.com", "expire": "1h", "scopes": "sign,encrypt" }' ``` ### Use the Token ```bash curl -X POST http://localhost:21000/api/sign \ -H "Content-Type: application/json" \ -H "Authorization: YOUR_ACCESS_TOKEN" \ -d '{"message": "Hello World"}' ``` ## Endpoints Register, login, logout, status, export Generate OAuth-style tokens for hosts Sign and encrypt messages Read and update BAP profile *** ## Wallet Management ### POST /api/register Create a new wallet with an encrypted master seed. Only call this once during initial setup. ```json { "password": "string (required)", "displayName": "string (optional)", "paymail": "string (optional)", "logo": "string (optional, URL or data URI)" } ``` | Field | Type | Description | | ------------- | ------ | ----------------------------------- | | `password` | string | Password to encrypt the master seed | | `displayName` | string | Your display name | | `paymail` | string | Your paymail address | | `logo` | string | Profile image URL or data URI | ```json { "success": true } ``` *** ### POST /api/login Unlock the wallet by decrypting the master seed. ```json { "password": "string (required)" } ``` ```json { "success": true } ``` Must be called after server restart or `/api/logout` before using protected endpoints. *** ### POST /api/logout Lock the wallet by clearing the in-memory decrypted seed. ```json { "success": true } ``` *** ### GET /api/status Check the current wallet status. ```json { "seed": true, "unlocked": true, "keys": [...], "states": [...] } ``` | Field | Type | Description | | ---------- | ------- | ------------------------------------- | | `seed` | boolean | `true` if wallet exists | | `unlocked` | boolean | `true` if wallet is unlocked | | `keys` | array | Derived keys (empty if locked) | | `states` | array | Access token states (empty if locked) | *** ### POST /api/export Export the master seed and mnemonic phrase. Never share your seed or mnemonic. Anyone with access has full control of your identity. ```json { "password": "string (required)" } ``` ```json { "seed": "hex-encoded-seed", "mnemonic": "twelve or twenty-four word phrase" } ``` *** ## Access Tokens ### POST /api/auth Generate an OAuth-style access token for a specific web host. ```json { "password": "string (required)", "host": "string (required)", "expire": "string (optional, default: 'once')", "scopes": "string (optional, comma-separated)", "icon": "string (optional)" } ``` **Expire Options:** | Value | Duration | | --------- | -------------------- | | `once` | 10 seconds (default) | | `1h` | 1 hour | | `1d` | 1 day | | `1w` | 1 week | | `1m` | 1 month | | `forever` | No expiration | **Scope Options:** | Scope | Description | | --------------- | ----------------------- | | `sign` | Sign messages | | `encrypt` | Encrypt messages | | `decrypt` | Decrypt messages | | `read_profile` | Read BAP identity | | `write_profile` | Modify BAP identity | | `read_state` | Read per-host state | | `write_state` | Write per-host state | | `fund` | Request funding/payment | | `transfer` | Transfer tokens/assets | ```json { "success": true, "accessToken": "uuid-v4-token", "expireTime": 1234567890123, "host": "example.com" } ``` *** ## Cryptographic Operations ### POST /api/sign Sign a message with the derived Bitcoin private key for the authenticated host. Requires `Authorization: ACCESS_TOKEN` header (no "Bearer" prefix) ```json { "message": "string (required)", "encoding": "string (optional, default: 'utf8')" } ``` | Field | Type | Description | | ---------- | ------ | -------------------------- | | `message` | string | The message to sign | | `encoding` | string | `utf8`, `hex`, or `base64` | ```json { "address": "1BitcoinAddress...", "sig": "signature-string", "message": "original-message", "ts": 1234567890123 } ``` *** ### POST /api/encrypt Encrypt a message using ECIES. Requires `Authorization: ACCESS_TOKEN` header with `encrypt` scope ```json { "message": "string (required)" } ``` ```json { "encrypted": "encrypted-message-data" } ``` *** ## Identity Management ### GET /api/profile Retrieve the global BAP identity profile. No authentication required. ```json { "host": "global", "displayName": "Alice", "paymail": "alice@example.com", "logo": "https://...", "bapID": "identity-key-string" } ``` *** ### POST /api/profile Update the global BAP identity profile. ```json { "displayName": "string (optional)", "paymail": "string (optional)", "logo": "string (optional)", "customField": "any value" } ``` ```json { "success": true } ``` *** ## Error Handling All errors return a consistent format: ```json { "error": "Error message description", "code": 1, "success": false } ``` | Code | Description | | ---- | ---------------------------- | | `1` | Wallet is locked | | `2` | Missing authorization header | | `3` | Invalid access token | | `5` | Access token has expired | | HTTP Status | Description | | ----------- | ---------------------------------------- | | `200` | Success | | `400` | Bad Request - missing required fields | | `401` | Unauthorized - invalid password or token | | `417` | Expectation Failed - wallet not created | | `500` | Internal Server Error | ## Configuration ### CORS Configure allowed origins: ```bash TOKENPASS_ORIGIN_WHITELIST=https://app1.com,https://app2.com bun dev ``` ### Storage All data is stored in `~/.tokenpass/`: | File | Description | | ---------- | ----------------------------------- | | `seed.db` | Encrypted master seed (AES-256-CBC) | | `keys.db` | Derived Bitcoin keys per host | | `state.db` | Access tokens and per-host state | --- # Authentication URL: /docs/authentication How Bitcoin-based authentication works in TokenPass # Authentication TokenPass uses Bitcoin cryptography for authentication. This provides several advantages over traditional auth systems. ## How It Works 1. **Key Derivation** - TokenPass uses Type42 (BRC-42/BRC-43) to derive unique keys for each application 2. **Message Signing** - Authentication is done by signing messages with BSM (Bitcoin Signed Message) 3. **Verification** - Any party can verify signatures using only the public key ## Flow >TP: 1. Request signature TP-->>App: 2. Return signature App->>Server: 3. Send request with signature Server-->>App: 4. Verify & respond `} /> ## Per-App Key Isolation Each website gets a unique derived key. This means: * Apps can't track you across sites * Compromising one app doesn't compromise others * You maintain a single master identity ## OAuth-Compatible TokenPass acts as an OAuth provider, making it easy to integrate with existing auth flows: ```typescript // Redirect to TokenPass for auth window.location.href = 'http://localhost:21000/auth?' + new URLSearchParams({ redirect: 'https://myapp.com/callback', scopes: 'sign,encrypt' }); ``` ## Token Scopes Available scopes: * `sign` - Sign messages * `encrypt` - Encrypt/decrypt data * `identity` - Read identity info --- # TokenPass Documentation URL: /docs Your personal identity server with Bitcoin-backed authentication # Welcome to TokenPass TokenPass is your personal identity server. Be your own OAuth provider with Bitcoin-backed authentication. No cloud accounts, no centralized dependencies. ## Quick Start ```bash bunx @sigma-auth/tokenpass-server ``` This starts the TokenPass server on `http://localhost:21000`. ## Core Concepts * **Type42 (BRC-42/BRC-43)** - Key derivation for per-app isolation * **BAP** - Bitcoin Attestation Protocol for identity * **BSM** - Bitcoin Signed Message for authentication * **ECIES** - End-to-end encryption using Bitcoin keys ## Next Steps * [API Reference](/docs/api) - Complete API documentation * [Authentication](/docs/authentication) - How authentication works * [Integration](/docs/integration) - Integrate with your app --- # Integration Guide URL: /docs/integration Integrate TokenPass authentication into your application # Integration Guide This guide shows how to integrate TokenPass into your application. ## Using Better Auth Plugin The easiest way to integrate TokenPass is with the Better Auth plugin: ```bash bun add @sigma-auth/better-auth-plugin better-auth ``` ### Server Setup ```typescript import { betterAuth } from "better-auth"; import { sigmaAuth } from "@sigma-auth/better-auth-plugin"; export const auth = betterAuth({ plugins: [ sigmaAuth({ tokenpassUrl: "http://localhost:21000" }) ] }); ``` ### Client Setup ```typescript import { createAuthClient } from "better-auth/client"; import { sigmaAuthClient } from "@sigma-auth/better-auth-plugin/client"; export const authClient = createAuthClient({ plugins: [sigmaAuthClient()] }); // Sign in with TokenPass await authClient.signIn.sigma(); ``` ## Direct API Integration If you prefer direct integration: ### 1. Request Authentication ```typescript // Redirect user to TokenPass const params = new URLSearchParams({ redirect: 'https://yourapp.com/callback', host: 'yourapp.com', scopes: 'sign' }); window.location.href = `http://localhost:21000/auth?${params}`; ``` ### 2. Handle Callback ```typescript // On your callback page const url = new URL(window.location.href); const signature = url.searchParams.get('signature'); const address = url.searchParams.get('address'); const message = url.searchParams.get('message'); // Verify the signature on your server const verified = await verifySignature({ signature, address, message }); ``` ### 3. Verify Signature Use the `bsv` library to verify: ```typescript import { BSM } from '@bsv/sdk'; function verifySignature({ signature, address, message }) { return BSM.verify(message, signature, address); } ``` ## React Hook Example ```typescript import { useState } from 'react'; export function useTokenPass() { const [user, setUser] = useState(null); const signIn = () => { const params = new URLSearchParams({ redirect: window.location.origin + '/auth/callback', host: window.location.host, scopes: 'sign' }); window.location.href = `http://localhost:21000/auth?${params}`; }; const handleCallback = async (searchParams) => { const signature = searchParams.get('signature'); const address = searchParams.get('address'); // Verify with your backend const res = await fetch('/api/auth/verify', { method: 'POST', body: JSON.stringify({ signature, address }) }); if (res.ok) { setUser(await res.json()); } }; return { user, signIn, handleCallback }; } ``` ## Security Considerations * Always verify signatures on your server, not the client * Use HTTPS in production * Validate the `host` parameter matches your domain * Set appropriate token expiry times