Widget API Reference
ProofOfSpendWidget
Section titled “ProofOfSpendWidget”The main widget component for integrating Proof of Spend into your React application.
interface ProofOfSpendWidgetProps { apiUrl: string; onVerified: (data: VerificationData) => void; onError?: (error: Error) => void; theme?: 'light' | 'dark'; providers?: Provider[]; className?: string;}| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
apiUrl | string | Yes | - | OAuth backend base URL |
onVerified | (data: VerificationData) => void | Yes | - | Called when task is verified |
onError | (error: Error) => void | No | undefined | Error handler callback |
theme | 'light' | 'dark' | No | 'light' | Widget color theme |
providers | Provider[] | No | All providers | Available OAuth providers |
className | string | No | '' | Custom CSS class |
Example
Section titled “Example”import { ProofOfSpendWidget } from '@proof-of-spend/widget';
function App() { const handleVerified = (data: VerificationData) => { console.log('Task completed:', data); // Store verification proof };
const handleError = (error: Error) => { console.error('Widget error:', error); // Show error to user };
return ( <ProofOfSpendWidget apiUrl="https://oauth.example.com" onVerified={handleVerified} onError={handleError} theme="dark" providers={['openai', 'anthropic']} /> );}useProofOfSpend Hook
Section titled “useProofOfSpend Hook”Custom React hook for building your own UI around the Proof of Spend logic.
const { state, task, response, verificationData, error, setResponse, selectProvider, fetchNewTask, submitResponse, reset,} = useProofOfSpend(config);Config
Section titled “Config”interface UseProofOfSpendConfig { apiUrl: string; providers?: Provider[];}Return Value
Section titled “Return Value”interface UseProofOfSpendReturn { // State state: WidgetState; task: AnnotationTask | null; response: string; verificationData: VerificationData | null; error: Error | null;
// Actions setResponse: (response: string) => void; selectProvider: (provider: Provider) => Promise<void>; fetchNewTask: () => Promise<void>; submitResponse: () => Promise<void>; reset: () => void;}State Machine
Section titled “State Machine”The hook uses a state machine with the following states:
type WidgetState = | 'loading' // Initial state, fetching config | 'provider-selection' // User selects OAuth provider | 'task-ready' // Task loaded and ready | 'submitting' // Submitting response | 'verifying' // Verifying API call | 'verified' // Task verified successfully | 'error'; // Error occurredExample
Section titled “Example”import { useProofOfSpend } from '@proof-of-spend/widget';
function CustomWidget() { const { state, task, response, setResponse, selectProvider, submitResponse, error, } = useProofOfSpend({ apiUrl: 'https://oauth.example.com', });
if (state === 'loading') { return <div>Loading...</div>; }
if (state === 'provider-selection') { return ( <div> <h2>Select Provider</h2> <button onClick={() => selectProvider('openai')}> OpenAI </button> <button onClick={() => selectProvider('anthropic')}> Anthropic </button> </div> ); }
if (state === 'task-ready' && task) { return ( <div> <h2>{task.category}</h2> <p>{task.prompt}</p> <textarea value={response} onChange={(e) => setResponse(e.target.value)} placeholder="Paste API response here" /> <button onClick={submitResponse}> Submit </button> </div> ); }
if (state === 'error') { return <div>Error: {error?.message}</div>; }
return null;}Provider
Section titled “Provider”type Provider = 'openai' | 'anthropic' | 'google';AnnotationTask
Section titled “AnnotationTask”interface AnnotationTask { id: string; category: string; prompt: string; examples?: string[]; metadata?: Record<string, unknown>;}VerificationData
Section titled “VerificationData”interface VerificationData { taskId: string; response: string; provider: Provider; cost: number; timestamp: string; proof: { accessToken: string; apiCallHash: string; signature: string; };}WidgetError
Section titled “WidgetError”interface WidgetError extends Error { code: string; details?: unknown;}Error Codes:
PROVIDER_AUTH_FAILED: OAuth authorization failedTASK_FETCH_FAILED: Failed to fetch annotation taskSUBMISSION_FAILED: Failed to submit responseVERIFICATION_FAILED: Failed to verify API callNETWORK_ERROR: Network request failed
ProofOfSpendAPI
Section titled “ProofOfSpendAPI”Low-level API client for direct integration.
Constructor
Section titled “Constructor”const api = new ProofOfSpendAPI(baseUrl: string);Methods
Section titled “Methods”fetchTask
Section titled “fetchTask”Fetch an annotation task.
async fetchTask(accessToken: string): Promise<AnnotationTask>Example:
const task = await api.fetchTask('ACCESS_TOKEN');console.log(task.prompt);submitAnnotation
Section titled “submitAnnotation”Submit an annotation response.
async submitAnnotation( taskId: string, response: string, accessToken: string): Promise<VerificationData>Example:
const verification = await api.submitAnnotation( 'task_123', 'API response text', 'ACCESS_TOKEN');console.log(verification.proof);getCategories
Section titled “getCategories”Get available annotation categories.
async getCategories(): Promise<string[]>Example:
const categories = await api.getCategories();console.log(categories); // ['sentiment', 'classification', ...]Styling
Section titled “Styling”The widget uses CSS modules and can be customized via CSS variables:
.proof-of-spend-widget { --widget-bg: #ffffff; --widget-text: #000000; --widget-primary: #0066cc; --widget-border: #e0e0e0; --widget-radius: 8px;}
.proof-of-spend-widget[data-theme="dark"] { --widget-bg: #1a1a1a; --widget-text: #ffffff; --widget-primary: #3399ff; --widget-border: #333333;}Events
Section titled “Events”The widget emits custom events that can be listened to:
// Listen for state changeswidget.addEventListener('statechange', (event) => { console.log('New state:', event.detail.state);});
// Listen for task loadedwidget.addEventListener('taskloaded', (event) => { console.log('Task:', event.detail.task);});
// Listen for verification completewidget.addEventListener('verified', (event) => { console.log('Verification:', event.detail.data);});