@lombard.finance/sdk-devtools 0.1.0-canary-2.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +348 -0
- package/dist/index.d.ts +830 -0
- package/dist/index.js +1644 -0
- package/dist/index.js.map +1 -0
- package/package.json +70 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/provider/DevToolsProvider.tsx","../src/bridge/DevToolsBridge.ts","../src/components/DevToolsPanel.tsx","../src/components/EventLog.tsx","../src/components/NetworkLog.tsx","../src/components/ReducerLog.tsx","../src/components/StateInspector.tsx","../src/components/StatusBadge.tsx","../src/components/StepIndicator.tsx","../src/hooks/useDevTools.ts","../src/hooks/useMockWallet.ts"],"sourcesContent":["/**\n * SDK DevTools - Type Definitions\n *\n * Core types for the Lombard SDK DevTools package.\n * These are framework-agnostic and can be used with any UI framework.\n */\n\n// ─────────────────────────────────────────────────────────────────\n// SDK Event Types\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * Represents an event emitted by the SDK\n */\nexport interface DevToolsEvent {\n /** Unique event ID */\n id: string;\n\n /** Event type (e.g., 'status-change', 'error', 'completed') */\n type: string;\n\n /** Unix timestamp when event occurred */\n timestamp: number;\n\n /** Event payload data */\n data: unknown;\n\n /** Source action name (e.g., 'BtcStake', 'EvmUnstake') */\n source?: string;\n\n /** Whether this event came from the SDK's built-in event emitter */\n isSDKEvent: boolean;\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Reducer/State Log Types\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * Log entry for reducer actions (Redux DevTools style)\n */\nexport interface ReducerLogEntry {\n /** Unique log ID */\n id: string;\n\n /** Unix timestamp when action was dispatched */\n timestamp: number;\n\n /** The dispatched action */\n action: {\n type: string;\n payload?: unknown;\n };\n\n /** State before action */\n prevState: unknown;\n\n /** State after action */\n nextState: unknown;\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Action Monitoring Types\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * Minimal interface for monitorable SDK actions\n * Matches the SDK's MonitorableAction interface\n */\nexport interface MonitorableAction {\n /** Current status of the action */\n readonly status: string;\n\n /** Whether an async operation is in progress */\n readonly isLoading: boolean;\n\n /** Error that occurred (if any) */\n readonly error: Error | null;\n\n /** Whether the action has failed */\n readonly isFailed: boolean;\n\n /** Subscribe to events */\n on(event: string, handler: (...args: unknown[]) => void): () => void;\n}\n\n/**\n * Registered action with metadata\n */\nexport interface RegisteredAction {\n /** Unique name for this action instance */\n name: string;\n\n /** The action instance */\n action: MonitorableAction;\n\n /** When the action was registered */\n registeredAt: number;\n\n /** Category (btc, evm, solana, etc.) */\n category?: string;\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Flow Step Types\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * Represents a step in an action flow\n */\nexport interface FlowStep {\n /** Step identifier */\n id: string;\n\n /** Display label */\n label: string;\n\n /** Optional description */\n description?: string;\n\n /** Step status */\n status: 'pending' | 'current' | 'completed' | 'error';\n}\n\n// ─────────────────────────────────────────────────────────────────\n// DevTools Configuration\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * Position options for the floating widget\n */\nexport type DevToolsPosition =\n | 'bottom-right'\n | 'bottom-left'\n | 'top-right'\n | 'top-left';\n\n/**\n * Theme options for DevTools\n */\nexport type DevToolsTheme = 'dark' | 'light' | 'system';\n\n/**\n * Configuration options for DevTools\n */\nexport interface DevToolsConfig {\n /** Widget position on screen */\n position?: DevToolsPosition;\n\n /** Whether to start open or collapsed */\n defaultOpen?: boolean;\n\n /** Theme preference */\n theme?: DevToolsTheme;\n\n /** Show environment indicator */\n showEnvironment?: boolean;\n\n /** Enable console logging alongside widget */\n consoleLogging?: boolean;\n\n /** Maximum number of events to retain */\n maxEvents?: number;\n\n /** Maximum number of reducer logs to retain */\n maxReducerLogs?: number;\n}\n\n/**\n * Default DevTools configuration\n */\nexport const DEFAULT_DEVTOOLS_CONFIG: Required<DevToolsConfig> = {\n position: 'bottom-right',\n defaultOpen: false,\n theme: 'dark',\n showEnvironment: true,\n consoleLogging: false,\n maxEvents: 100,\n maxReducerLogs: 50,\n};\n\n// ─────────────────────────────────────────────────────────────────\n// Mock Wallet Types\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * Mock addresses for testing without real wallets\n */\nexport interface MockAddresses {\n evm: string;\n bitcoin: string;\n solana: string;\n sui: string;\n starknet: string;\n}\n\n/**\n * Mock wallet state and controls\n */\nexport interface MockWalletState {\n /** Whether mock wallet is enabled */\n isEnabled: boolean;\n\n /** Current mock address (based on chain type) */\n address: string;\n\n /** Current mock chain ID */\n chainId: number;\n\n /** Whether mock wallet can sign (always false) */\n canSign: boolean;\n\n /** Enable mock wallet */\n enable: () => void;\n\n /** Disable mock wallet */\n disable: () => void;\n\n /** Toggle mock wallet */\n toggle: () => void;\n\n /** Set mock chain */\n setChain: (chainId: number) => void;\n\n /** Get mock address for a specific chain type */\n getAddress: (chainType: keyof MockAddresses) => string;\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Warning Types\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * Warning severity levels\n */\nexport type WarningSeverity = 'info' | 'warning' | 'error';\n\n/**\n * DevTools warning message\n */\nexport interface DevToolsWarning {\n /** Unique warning ID */\n id: string;\n\n /** Warning severity */\n severity: WarningSeverity;\n\n /** Warning title */\n title: string;\n\n /** Warning message */\n message: string;\n\n /** Link to documentation */\n docsLink?: string;\n\n /** Suggested code fix */\n suggestedFix?: string;\n\n /** When the warning was triggered */\n timestamp: number;\n}\n\n// ─────────────────────────────────────────────────────────────────\n// API Request/Response Types (for Network tab)\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * HTTP method types\n */\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n\n/**\n * API request event - logged when a request is initiated\n */\nexport interface ApiRequestEvent {\n /** Unique request ID */\n id: string;\n\n /** Event type */\n type: 'api-request';\n\n /** HTTP method */\n method: HttpMethod;\n\n /** Request URL (full or relative) */\n url: string;\n\n /** Request payload (body or params) */\n payload?: unknown;\n\n /** Request headers (selected) */\n headers?: Record<string, string>;\n\n /** When the request was initiated */\n timestamp: number;\n\n /** Source/origin of the request (e.g., 'api.deposits', 'btc.stake') */\n source?: string;\n}\n\n/**\n * API response event - logged when a response is received\n */\nexport interface ApiResponseEvent {\n /** Unique response ID */\n id: string;\n\n /** Event type */\n type: 'api-response';\n\n /** Corresponding request ID */\n requestId: string;\n\n /** HTTP status code */\n status: number;\n\n /** Status text (e.g., 'OK', 'Not Found') */\n statusText?: string;\n\n /** Response data (parsed) */\n data?: unknown;\n\n /** Error message if request failed */\n error?: string;\n\n /** Request duration in milliseconds */\n duration: number;\n\n /** When the response was received */\n timestamp: number;\n}\n\n/**\n * Combined API event for the Network log\n */\nexport interface NetworkLogEntry {\n /** Request details */\n request: ApiRequestEvent;\n\n /** Response details (null if pending) */\n response: ApiResponseEvent | null;\n\n /** Whether the request is still pending */\n isPending: boolean;\n\n /** Whether the request failed */\n isFailed: boolean;\n}\n","/**\n * DevToolsProvider - React Context Provider for DevTools\n *\n * Provides DevTools functionality throughout your app via React Context.\n * This is the recommended way to integrate DevTools in larger applications.\n *\n * @module sdk-devtools/provider\n */\n\nimport {\n createContext,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from 'react';\n\nimport { DevToolsBridge } from '../bridge/DevToolsBridge';\nimport type {\n DevToolsConfig,\n DevToolsEvent,\n MonitorableAction,\n NetworkLogEntry,\n RegisteredAction,\n} from '../types';\n\n// ─────────────────────────────────────────────────────────────────\n// Context Type\n// ─────────────────────────────────────────────────────────────────\n\ninterface DevToolsContextValue {\n /** All collected events */\n events: DevToolsEvent[];\n\n /** All registered actions */\n actions: Map<string, RegisteredAction>;\n\n /** Network log entries (API requests/responses) */\n networkLog: NetworkLogEntry[];\n\n /** Register an action for monitoring */\n registerAction: (\n name: string,\n action: MonitorableAction,\n options?: { category?: string },\n ) => () => void;\n\n /** Unregister an action */\n unregisterAction: (name: string) => void;\n\n /** Clear all events */\n clearEvents: () => void;\n\n /** Clear network log */\n clearNetworkLog: () => void;\n\n /** Get current state of all actions */\n getStateSummary: () => Record<\n string,\n { status: string; isLoading: boolean; hasError: boolean }\n >;\n\n /** The underlying bridge instance */\n bridge: DevToolsBridge;\n\n /** Whether DevTools is enabled */\n isEnabled: boolean;\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Context\n// ─────────────────────────────────────────────────────────────────\n\nconst DevToolsContext = createContext<DevToolsContextValue | null>(null);\n\n// ─────────────────────────────────────────────────────────────────\n// Provider Props\n// ─────────────────────────────────────────────────────────────────\n\nexport interface DevToolsProviderProps {\n children: ReactNode;\n\n /** DevTools configuration */\n config?: DevToolsConfig;\n\n /**\n * Whether DevTools is enabled.\n *\n * Default: `process.env.NODE_ENV !== 'production'`\n *\n * For development/testing tools (like sdk-demo), you may want to always\n * enable DevTools with `enabled={true}` regardless of environment, so\n * developers can debug production SDK endpoints.\n */\n enabled?: boolean;\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Provider Component\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * DevTools Provider\n *\n * Wrap your app with this provider to enable DevTools functionality.\n *\n * The `enabled` prop defaults to `false` in production (NODE_ENV === 'production')\n * as a safety net. However, you can explicitly override this:\n * - `enabled={true}` - Always enable (useful for dev tools testing prod SDK)\n * - `enabled={false}` - Always disable\n *\n * @example\n * ```tsx\n * // Basic usage - auto-disabled in production builds\n * function App() {\n * return (\n * <DevToolsProvider>\n * <MyApp />\n * </DevToolsProvider>\n * );\n * }\n *\n * // Always enable (for developer tools/playgrounds)\n * function DevToolApp() {\n * return (\n * <DevToolsProvider enabled={true}>\n * <MyApp />\n * </DevToolsProvider>\n * );\n * }\n * ```\n */\nexport function DevToolsProvider({\n children,\n config,\n enabled = process.env.NODE_ENV !== 'production',\n}: DevToolsProviderProps) {\n // Create bridge as state to ensure proper lifecycle with React StrictMode\n const [bridge] = useState(() => new DevToolsBridge(config));\n\n // State for React re-renders\n const [events, setEvents] = useState<DevToolsEvent[]>([]);\n const [actions, setActions] = useState<Map<string, RegisteredAction>>(\n new Map(),\n );\n const [networkLog, setNetworkLog] = useState<NetworkLogEntry[]>([]);\n\n // Counter to force effect re-run after mount\n const [mountId, setMountId] = useState(0);\n\n // Increment mount counter on mount to ensure subscription runs\n useEffect(() => {\n setMountId((prev) => prev + 1);\n }, []);\n\n // Subscribe to bridge updates\n useEffect(() => {\n if (!enabled || mountId === 0) return;\n\n console.log(\n '[DevToolsProvider] Setting up event subscriptions, mountId:',\n mountId,\n );\n\n // IMPORTANT: Sync existing events immediately on subscription setup\n // This catches any events that were captured before the subscription was ready\n // (e.g., during React StrictMode's double-mount, or if action was registered early)\n const existingEvents = bridge.getEvents();\n const existingActions = bridge.getActions();\n\n if (existingEvents.length > 0) {\n console.log(\n '[DevToolsProvider] Syncing existing events:',\n existingEvents.length,\n );\n setEvents(existingEvents);\n }\n\n if (existingActions.size > 0) {\n console.log(\n '[DevToolsProvider] Syncing existing actions:',\n existingActions.size,\n );\n setActions(existingActions);\n }\n\n // Subscribe to new events going forward\n const unsubEvent = bridge.onEvent((event) => {\n console.log('[DevToolsProvider] Event received:', event);\n const newEvents = bridge.getEvents();\n console.log('[DevToolsProvider] Setting events:', newEvents.length);\n setEvents(newEvents);\n });\n\n const unsubState = bridge.onStateChange((newActions) => {\n console.log(\n '[DevToolsProvider] State changed:',\n newActions.size,\n 'actions',\n );\n setActions(newActions);\n });\n\n // Subscribe to network log changes\n const unsubNetwork = bridge.onNetworkChange((entries) => {\n console.log(\n '[DevToolsProvider] Network log updated:',\n entries.length,\n 'entries',\n );\n setNetworkLog(entries);\n });\n\n // Sync existing network log\n const existingNetworkLog = bridge.getNetworkLog();\n if (existingNetworkLog.length > 0) {\n console.log(\n '[DevToolsProvider] Syncing existing network log:',\n existingNetworkLog.length,\n );\n setNetworkLog(existingNetworkLog);\n }\n\n return () => {\n console.log('[DevToolsProvider] Cleaning up subscriptions');\n unsubEvent();\n unsubState();\n unsubNetwork();\n };\n }, [enabled, bridge, mountId]);\n\n // Cleanup bridge on unmount only\n useEffect(() => {\n return () => {\n console.log('[DevToolsProvider] Destroying bridge');\n bridge.destroy();\n };\n }, [bridge]);\n\n // Callbacks\n const registerAction = useCallback(\n (\n name: string,\n action: MonitorableAction,\n options?: { category?: string },\n ) => {\n if (!enabled) return () => {};\n return bridge.registerAction(name, action, options);\n },\n [bridge, enabled],\n );\n\n const unregisterAction = useCallback(\n (name: string) => {\n if (!enabled) return;\n bridge.unregisterAction(name);\n },\n [bridge, enabled],\n );\n\n const clearEvents = useCallback(() => {\n bridge.clearEvents();\n setEvents([]);\n }, [bridge]);\n\n const clearNetworkLog = useCallback(() => {\n bridge.clearNetworkLog();\n setNetworkLog([]);\n }, [bridge]);\n\n const getStateSummary = useCallback(() => {\n return bridge.getStateSummary();\n }, [bridge]);\n\n // Context value\n const value = useMemo(\n (): DevToolsContextValue => ({\n events,\n actions,\n networkLog,\n registerAction,\n unregisterAction,\n clearEvents,\n clearNetworkLog,\n getStateSummary,\n bridge,\n isEnabled: enabled,\n }),\n [\n events,\n actions,\n networkLog,\n registerAction,\n unregisterAction,\n clearEvents,\n clearNetworkLog,\n getStateSummary,\n bridge,\n enabled,\n ],\n );\n\n return (\n <DevToolsContext.Provider value={value}>\n {children}\n </DevToolsContext.Provider>\n );\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Hook to use context\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * Hook to access DevTools context\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { registerAction, events } = useDevToolsContext();\n *\n * useEffect(() => {\n * const action = sdk.btc.stake({ ... });\n * return registerAction('stake', action);\n * }, []);\n *\n * return <div>Events: {events.length}</div>;\n * }\n * ```\n */\nexport function useDevToolsContext(): DevToolsContextValue {\n const context = useContext(DevToolsContext);\n\n if (!context) {\n throw new Error(\n 'useDevToolsContext must be used within a DevToolsProvider',\n );\n }\n\n return context;\n}\n\n/**\n * Hook to register an action with DevTools (from within context)\n *\n * @example\n * ```tsx\n * function StakeComponent() {\n * const stake = useMemo(() => sdk.btc.stake({ ... }), []);\n * useRegisterAction('stake', stake);\n *\n * return <button onClick={() => stake.prepare({ ... })}>Stake</button>;\n * }\n * ```\n */\nexport function useRegisterAction(\n name: string,\n action: MonitorableAction | null,\n category?: string,\n): void {\n const { registerAction } = useDevToolsContext();\n\n // Use refs to avoid re-registration on every render\n // We only want to re-register when name or action actually changes\n useEffect(() => {\n if (!action) return;\n return registerAction(name, action, category ? { category } : undefined);\n }, [name, action, registerAction]);\n}\n","/**\n * DevToolsBridge - Connects SDK actions to DevTools automatically\n *\n * This is the core integration layer that makes DevTools \"just work\"\n * with the Lombard SDK. It automatically subscribes to action events\n * and provides the collected data to DevTools components.\n *\n * ## How It Works\n *\n * 1. Wrap the SDK at initialization\n * 2. Automatically intercept action creation\n * 3. Subscribe to all action events\n * 4. Aggregate events/state for DevTools display\n *\n * @module sdk-devtools/bridge\n */\n\nimport {\n type ApiRequestEvent,\n type ApiResponseEvent,\n DEFAULT_DEVTOOLS_CONFIG,\n type DevToolsConfig,\n type DevToolsEvent,\n type HttpMethod,\n type MonitorableAction,\n type NetworkLogEntry,\n type RegisteredAction,\n} from '../types';\n\n// ─────────────────────────────────────────────────────────────────\n// Event Callback Types\n// ─────────────────────────────────────────────────────────────────\n\nexport type DevToolsEventCallback = (event: DevToolsEvent) => void;\nexport type DevToolsStateCallback = (\n actions: Map<string, RegisteredAction>,\n) => void;\n\n// ─────────────────────────────────────────────────────────────────\n// DevToolsBridge Class\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * DevToolsBridge - Collects events from all SDK actions\n *\n * Usage:\n * ```typescript\n * // Create bridge\n * const bridge = new DevToolsBridge();\n *\n * // Register an action\n * const stake = sdk.btc.stake({ ... });\n * bridge.registerAction('btc-stake', stake);\n *\n * // Subscribe to events\n * const unsubscribe = bridge.onEvent((event) => {\n * console.log('SDK Event:', event);\n * });\n *\n * // Get all events\n * const events = bridge.getEvents();\n *\n * // Get registered actions\n * const actions = bridge.getActions();\n * ```\n */\nexport class DevToolsBridge {\n private events: DevToolsEvent[] = [];\n private actions: Map<string, RegisteredAction> = new Map();\n private unsubscribers: Map<string, Array<() => void>> = new Map();\n private eventListeners: Set<DevToolsEventCallback> = new Set();\n private stateListeners: Set<DevToolsStateCallback> = new Set();\n private config: Required<DevToolsConfig>;\n private eventIdCounter = 0;\n\n // Network logging\n private networkLog: Map<string, NetworkLogEntry> = new Map();\n private networkListeners: Set<(entries: NetworkLogEntry[]) => void> =\n new Set();\n private requestIdCounter = 0;\n\n constructor(config?: DevToolsConfig) {\n this.config = { ...DEFAULT_DEVTOOLS_CONFIG, ...config };\n }\n\n // ─────────────────────────────────────────────────────────────────\n // Action Registration\n // ─────────────────────────────────────────────────────────────────\n\n /**\n * Register an SDK action for monitoring\n *\n * Automatically subscribes to all standard events:\n * - status-change\n * - error\n * - completed\n * - failed\n * - loading\n * - progress\n */\n registerAction(\n name: string,\n action: MonitorableAction,\n options?: { category?: string },\n ): () => void {\n // Store the action\n this.actions.set(name, {\n name,\n action,\n registeredAt: Date.now(),\n category: options?.category,\n });\n\n // Subscribe to standard SDK events\n const eventTypes = [\n 'status-change',\n 'error',\n 'completed',\n 'failed',\n 'loading',\n 'progress',\n ];\n\n const unsubscribers: Array<() => void> = [];\n\n for (const eventType of eventTypes) {\n try {\n const unsubscribe = action.on(eventType, (...args: unknown[]) => {\n this.handleEvent(name, eventType, args[0]);\n });\n if (typeof unsubscribe === 'function') {\n unsubscribers.push(unsubscribe);\n }\n } catch {\n // Some events might not be supported - that's ok\n }\n }\n\n this.unsubscribers.set(name, unsubscribers);\n this.notifyStateListeners();\n\n // Log registration\n this.handleEvent(name, 'registered', { status: action.status });\n\n // Return unregister function\n return () => {\n this.unregisterAction(name);\n };\n }\n\n /**\n * Unregister an action\n */\n unregisterAction(name: string): void {\n // Unsubscribe from events\n const unsubs = this.unsubscribers.get(name);\n if (unsubs) {\n unsubs.forEach((unsub) => {\n unsub();\n });\n this.unsubscribers.delete(name);\n }\n\n // Remove action\n this.actions.delete(name);\n this.notifyStateListeners();\n\n // Log unregistration\n this.handleEvent(name, 'unregistered', null);\n }\n\n // ─────────────────────────────────────────────────────────────────\n // Event Handling\n // ─────────────────────────────────────────────────────────────────\n\n private handleEvent(source: string, type: string, data: unknown): void {\n const event: DevToolsEvent = {\n id: `${++this.eventIdCounter}`,\n type,\n timestamp: Date.now(),\n data,\n source,\n isSDKEvent: true,\n };\n\n // Add to events array (with max limit)\n this.events.push(event);\n if (this.events.length > this.config.maxEvents) {\n this.events.shift();\n }\n\n // Console logging if enabled\n if (this.config.consoleLogging) {\n console.log(`[DevTools] ${source} → ${type}:`, data);\n }\n\n // Notify listeners\n this.notifyEventListeners(event);\n }\n\n private notifyEventListeners(event: DevToolsEvent): void {\n this.eventListeners.forEach((listener) => {\n try {\n listener(event);\n } catch (err) {\n console.error('[DevTools] Event listener error:', err);\n }\n });\n }\n\n private notifyStateListeners(): void {\n this.stateListeners.forEach((listener) => {\n try {\n listener(new Map(this.actions));\n } catch (err) {\n console.error('[DevTools] State listener error:', err);\n }\n });\n }\n\n // ─────────────────────────────────────────────────────────────────\n // Subscriptions\n // ─────────────────────────────────────────────────────────────────\n\n /**\n * Subscribe to new events\n */\n onEvent(callback: DevToolsEventCallback): () => void {\n this.eventListeners.add(callback);\n return () => this.eventListeners.delete(callback);\n }\n\n /**\n * Subscribe to action state changes\n */\n onStateChange(callback: DevToolsStateCallback): () => void {\n this.stateListeners.add(callback);\n return () => this.stateListeners.delete(callback);\n }\n\n // ─────────────────────────────────────────────────────────────────\n // Getters\n // ─────────────────────────────────────────────────────────────────\n\n /**\n * Get all collected events\n */\n getEvents(): DevToolsEvent[] {\n return [...this.events];\n }\n\n /**\n * Get all registered actions\n */\n getActions(): Map<string, RegisteredAction> {\n return new Map(this.actions);\n }\n\n /**\n * Get current state summary for all actions\n */\n getStateSummary(): Record<\n string,\n { status: string; isLoading: boolean; hasError: boolean }\n > {\n const summary: Record<\n string,\n { status: string; isLoading: boolean; hasError: boolean }\n > = {};\n\n this.actions.forEach((reg, name) => {\n summary[name] = {\n status: reg.action.status,\n isLoading: reg.action.isLoading,\n hasError: reg.action.isFailed,\n };\n });\n\n return summary;\n }\n\n // ─────────────────────────────────────────────────────────────────\n // Network Logging (API Requests/Responses)\n // ─────────────────────────────────────────────────────────────────\n\n /**\n * Log an API request\n *\n * Call this when an HTTP request is initiated.\n * Returns a request ID to correlate with the response.\n */\n logApiRequest(params: {\n method: HttpMethod;\n url: string;\n payload?: unknown;\n headers?: Record<string, string>;\n source?: string;\n }): string {\n const requestId = `req-${++this.requestIdCounter}`;\n\n const request: ApiRequestEvent = {\n id: requestId,\n type: 'api-request',\n method: params.method,\n url: params.url,\n payload: params.payload,\n headers: params.headers,\n timestamp: Date.now(),\n source: params.source,\n };\n\n const entry: NetworkLogEntry = {\n request,\n response: null,\n isPending: true,\n isFailed: false,\n };\n\n this.networkLog.set(requestId, entry);\n\n // Also log as a regular event for the Events tab\n this.handleEvent(params.source || 'api', 'api-request', {\n method: params.method,\n url: params.url,\n payload: params.payload,\n });\n\n // Console logging if enabled\n if (this.config.consoleLogging) {\n console.log(\n `[DevTools] API ${params.method} ${params.url}`,\n params.payload,\n );\n }\n\n this.notifyNetworkListeners();\n\n return requestId;\n }\n\n /**\n * Log an API response\n *\n * Call this when an HTTP response is received.\n * Pass the requestId returned from logApiRequest.\n */\n logApiResponse(params: {\n requestId: string;\n status: number;\n statusText?: string;\n data?: unknown;\n error?: string;\n }): void {\n const entry = this.networkLog.get(params.requestId);\n if (!entry) {\n console.warn(`[DevTools] No request found for ID: ${params.requestId}`);\n return;\n }\n\n const response: ApiResponseEvent = {\n id: `res-${params.requestId}`,\n type: 'api-response',\n requestId: params.requestId,\n status: params.status,\n statusText: params.statusText,\n data: params.data,\n error: params.error,\n duration: Date.now() - entry.request.timestamp,\n timestamp: Date.now(),\n };\n\n entry.response = response;\n entry.isPending = false;\n entry.isFailed = params.status >= 400 || !!params.error;\n\n // Also log as a regular event\n this.handleEvent(entry.request.source || 'api', 'api-response', {\n status: params.status,\n duration: response.duration,\n url: entry.request.url,\n error: params.error,\n });\n\n // Console logging if enabled\n if (this.config.consoleLogging) {\n const logFn = entry.isFailed ? console.error : console.log;\n logFn(\n `[DevTools] API Response ${params.status} (${response.duration}ms) ${entry.request.url}`,\n params.data || params.error,\n );\n }\n\n this.notifyNetworkListeners();\n }\n\n /**\n * Subscribe to network log changes\n */\n onNetworkChange(callback: (entries: NetworkLogEntry[]) => void): () => void {\n this.networkListeners.add(callback);\n return () => this.networkListeners.delete(callback);\n }\n\n /**\n * Get all network log entries\n */\n getNetworkLog(): NetworkLogEntry[] {\n return Array.from(this.networkLog.values()).sort(\n (a, b) => b.request.timestamp - a.request.timestamp,\n );\n }\n\n /**\n * Clear network log\n */\n clearNetworkLog(): void {\n this.networkLog.clear();\n this.notifyNetworkListeners();\n }\n\n private notifyNetworkListeners(): void {\n const entries = this.getNetworkLog();\n this.networkListeners.forEach((listener) => {\n try {\n listener(entries);\n } catch (err) {\n console.error('[DevTools] Network listener error:', err);\n }\n });\n }\n\n // ─────────────────────────────────────────────────────────────────\n // Utilities\n // ─────────────────────────────────────────────────────────────────\n\n /**\n * Clear all events\n */\n clearEvents(): void {\n this.events = [];\n }\n\n /**\n * Clear all registered actions\n */\n clearActions(): void {\n this.actions.forEach((_, name) => {\n this.unregisterAction(name);\n });\n }\n\n /**\n * Destroy the bridge\n */\n destroy(): void {\n this.clearActions();\n this.clearNetworkLog();\n this.eventListeners.clear();\n this.stateListeners.clear();\n this.networkListeners.clear();\n }\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Singleton Instance (optional convenience)\n// ─────────────────────────────────────────────────────────────────\n\nlet globalBridge: DevToolsBridge | null = null;\n\n/**\n * Get or create the global DevTools bridge\n */\nexport function getDevToolsBridge(config?: DevToolsConfig): DevToolsBridge {\n if (!globalBridge) {\n globalBridge = new DevToolsBridge(config);\n }\n return globalBridge;\n}\n\n/**\n * Reset the global DevTools bridge\n */\nexport function resetDevToolsBridge(): void {\n if (globalBridge) {\n globalBridge.destroy();\n globalBridge = null;\n }\n}\n","/**\n * DevToolsPanel - Main DevTools container with tabs\n *\n * Combined debug view showing SDK Events, State, and Action Log.\n * This is the main component you'd render in your app.\n *\n * @module sdk-devtools/components/DevToolsPanel\n */\n\nimport {\n Activity,\n Bug,\n Database,\n Maximize2,\n Minimize2,\n Terminal,\n Wifi,\n} from 'lucide-react';\nimport { useMemo, useState } from 'react';\n\nimport type { DevToolsEvent, NetworkLogEntry, ReducerLogEntry } from '../types';\nimport { EventLog } from './EventLog';\nimport { NetworkLog } from './NetworkLog';\nimport { ReducerLog } from './ReducerLog';\nimport { StateInspector } from './StateInspector';\n\n// ─────────────────────────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────────────────────────\n\ntype TabId = 'events' | 'reducer' | 'state' | 'network';\n\nexport interface DevToolsPanelProps {\n /** SDK events to display */\n events: DevToolsEvent[];\n\n /** Clear SDK events callback */\n onClearEvents: () => void;\n\n /** Reducer action logs */\n reducerLogs?: ReducerLogEntry[];\n\n /** Clear reducer logs callback */\n onClearReducerLogs?: () => void;\n\n /** Current state for inspection */\n state?: Record<string, unknown>;\n\n /** Network log entries */\n networkLog?: NetworkLogEntry[];\n\n /** Clear network log callback */\n onClearNetworkLog?: () => void;\n\n /** Initial tab to show */\n initialTab?: TabId;\n\n /** Whether to show minimized by default */\n defaultMinimized?: boolean;\n\n /** Custom class name */\n className?: string;\n\n /** Optional title */\n title?: string;\n\n /** Callback when minimize button is clicked (for external control) */\n onMinimize?: () => void;\n}\n\n/**\n * DevTools Panel Component\n *\n * Main container for all DevTools functionality with tabbed navigation.\n */\nexport function DevToolsPanel({\n events,\n onClearEvents,\n reducerLogs = [],\n onClearReducerLogs,\n state = {},\n networkLog = [],\n onClearNetworkLog,\n initialTab = 'events',\n defaultMinimized = false,\n className = '',\n title = 'DevTools',\n onMinimize,\n}: DevToolsPanelProps) {\n const [activeTab, setActiveTab] = useState<TabId>(initialTab);\n const [isMinimized, setIsMinimized] = useState(defaultMinimized);\n\n // Handle minimize - call external callback if provided, otherwise toggle internal state\n const handleMinimize = () => {\n if (onMinimize) {\n onMinimize();\n } else {\n setIsMinimized(true);\n }\n };\n\n const tabs = useMemo(\n () => [\n {\n id: 'events' as const,\n label: 'Events',\n icon: Terminal,\n count: events.length,\n },\n {\n id: 'network' as const,\n label: 'Network',\n icon: Wifi,\n count: networkLog.length,\n },\n {\n id: 'reducer' as const,\n label: 'Actions',\n icon: Activity,\n count: reducerLogs.length,\n },\n {\n id: 'state' as const,\n label: 'State',\n icon: Database,\n count: null,\n },\n ],\n [events.length, reducerLogs.length, networkLog.length],\n );\n\n if (isMinimized) {\n return (\n <button\n onClick={() => {\n setIsMinimized(false);\n }}\n className={`\n flex items-center gap-2 px-3 py-2 bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-lg \n text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors\n ${className}\n `}\n >\n <Bug className=\"w-4 h-4\" />\n <span className=\"text-xs font-medium\">{title}</span>\n {events.length > 0 && (\n <span className=\"text-[10px] px-1.5 py-0.5 bg-cyan-100 dark:bg-cyan-900/50 text-cyan-600 dark:text-cyan-400 rounded\">\n {events.length}\n </span>\n )}\n <Maximize2 className=\"w-3 h-3 ml-1\" />\n </button>\n );\n }\n\n return (\n <div\n className={`h-full flex flex-col bg-white dark:bg-gray-900 ${className}`}\n >\n {/* Tab Header */}\n <div className=\"flex items-center border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800\">\n <div className=\"flex items-center gap-1 px-2\">\n <Bug className=\"w-3.5 h-3.5 text-gray-400 dark:text-gray-500\" />\n <span className=\"text-[10px] text-gray-500 font-medium uppercase tracking-wider\">\n {title}\n </span>\n </div>\n\n <div className=\"flex-1 flex\">\n {tabs.map((tab) => (\n <button\n key={tab.id}\n onClick={() => {\n setActiveTab(tab.id);\n }}\n className={`\n flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium border-b-2 transition-colors\n ${\n activeTab === tab.id\n ? 'text-cyan-600 dark:text-cyan-400 border-cyan-500 dark:border-cyan-400 bg-white dark:bg-gray-900/50'\n : 'text-gray-500 dark:text-gray-400 border-transparent hover:text-gray-700 dark:hover:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700/30'\n }\n `}\n >\n <tab.icon className=\"w-3.5 h-3.5\" />\n {tab.label}\n {tab.count !== null && tab.count > 0 && (\n <span className=\"ml-1 px-1 py-0.5 bg-gray-200 dark:bg-gray-700 rounded text-[9px]\">\n {tab.count}\n </span>\n )}\n </button>\n ))}\n </div>\n\n {/* Minimize button */}\n <button\n onClick={handleMinimize}\n className=\"px-2 py-1 text-gray-400 dark:text-gray-500 hover:text-gray-600 dark:hover:text-gray-300 transition-colors\"\n title=\"Minimize\"\n >\n <Minimize2 className=\"w-3.5 h-3.5\" />\n </button>\n </div>\n\n {/* Tab Content */}\n <div className=\"flex-1 min-h-0 overflow-hidden\">\n {activeTab === 'events' && (\n <EventLog events={events} onClear={onClearEvents} />\n )}\n {activeTab === 'network' && (\n <NetworkLog\n entries={networkLog}\n onClear={onClearNetworkLog ?? (() => {})}\n />\n )}\n {activeTab === 'reducer' && (\n <ReducerLog\n logs={reducerLogs}\n onClear={onClearReducerLogs ?? (() => {})}\n />\n )}\n {activeTab === 'state' && (\n <div className=\"h-full overflow-auto p-2\">\n <StateInspector state={state} title=\"Current State\" />\n </div>\n )}\n </div>\n </div>\n );\n}\n","/**\n * EventLog - Console-style SDK event log\n *\n * Displays events from the SDK's built-in event emitter (BaseAction).\n * SDK events are clearly labeled to help developers understand\n * what events they'll receive when integrating the SDK.\n *\n * @module sdk-devtools/components/EventLog\n */\n\nimport { Terminal, Trash2, Zap } from 'lucide-react';\n\nimport type { DevToolsEvent } from '../types';\n\nexport interface EventLogProps {\n /** Events to display */\n events: DevToolsEvent[];\n\n /** Callback to clear events */\n onClear: () => void;\n\n /** Optional title override */\n title?: string;\n\n /** Whether to show the info banner */\n showInfoBanner?: boolean;\n\n /** Custom class name for the container */\n className?: string;\n}\n\n/**\n * Event Log Component\n *\n * Console-style log showing SDK events with timestamps and color coding.\n */\nexport function EventLog({\n events,\n onClear,\n title = 'SDK Event Log',\n showInfoBanner = true,\n className = '',\n}: EventLogProps) {\n // Count SDK events\n const sdkEventCount = events.filter((e) => e.isSDKEvent).length;\n\n return (\n <div className={`h-full flex flex-col ${className}`}>\n {/* Header */}\n <div className=\"flex items-center justify-between px-3 py-1.5 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800\">\n <div className=\"flex items-center gap-2 text-xs text-gray-600 dark:text-gray-400\">\n <Terminal className=\"w-3.5 h-3.5\" />\n <span>{title}</span>\n {events.length > 0 && (\n <span className=\"flex items-center gap-1 px-1.5 py-0.5 bg-cyan-100 dark:bg-cyan-900/50 border border-cyan-200 dark:border-cyan-700/50 rounded text-[10px] text-cyan-600 dark:text-cyan-400\">\n <Zap className=\"w-2.5 h-2.5\" />\n {sdkEventCount} SDK events\n </span>\n )}\n </div>\n\n {events.length > 0 && (\n <button\n onClick={onClear}\n className=\"flex items-center gap-1 text-[10px] text-gray-500 hover:text-gray-700 dark:hover:text-gray-300 transition-colors\"\n >\n <Trash2 className=\"w-3 h-3\" />\n Clear\n </button>\n )}\n </div>\n\n {/* Info banner about SDK events */}\n {showInfoBanner && (\n <div className=\"px-3 py-1 bg-gray-100 dark:bg-gray-800/50 border-b border-gray-200 dark:border-gray-700/50 text-[10px] text-gray-500\">\n 💡 These events are emitted by the SDK's{' '}\n <code className=\"text-gray-900 dark:text-white font-semibold\">\n action.on()\n </code>{' '}\n method\n </div>\n )}\n\n {/* Event List - scrollable */}\n <div className=\"flex-1 overflow-y-auto p-2 font-mono text-[11px] leading-relaxed\">\n {events.length === 0 ? (\n <div className=\"text-gray-400 dark:text-gray-600 text-center py-4\">\n <p>SDK events will appear here...</p>\n </div>\n ) : (\n <div className=\"space-y-0.5\">\n {events.map((event) => (\n <EventRow key={event.id} event={event} />\n ))}\n </div>\n )}\n </div>\n </div>\n );\n}\n\n/**\n * Single event row\n */\nfunction EventRow({ event }: { event: DevToolsEvent }) {\n return (\n <div className=\"flex gap-2 hover:bg-gray-100 dark:hover:bg-gray-800/50 px-1 py-0.5 rounded\">\n <span className=\"text-gray-400 dark:text-gray-600 flex-shrink-0\">\n {formatTime(event.timestamp)}\n </span>\n {event.isSDKEvent && (\n <span className=\"flex-shrink-0 text-[9px] px-1 py-0.5 bg-cyan-100 dark:bg-cyan-900/30 text-cyan-600 dark:text-cyan-500 rounded border border-cyan-200 dark:border-cyan-800/50\">\n SDK\n </span>\n )}\n {event.source && (\n <span className=\"flex-shrink-0 text-[9px] px-1 py-0.5 bg-purple-100 dark:bg-purple-900/30 text-purple-600 dark:text-purple-400 rounded border border-purple-200 dark:border-purple-800/50\">\n {event.source}\n </span>\n )}\n <span className={`flex-shrink-0 ${getEventColor(event.type)}`}>\n {event.type}\n </span>\n <span className=\"text-gray-400 dark:text-gray-500\">→</span>\n <span className=\"text-gray-600 dark:text-gray-400 truncate\">\n {formatEventData(event.data)}\n </span>\n </div>\n );\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Utilities\n// ─────────────────────────────────────────────────────────────────\n\nfunction formatTime(timestamp: number): string {\n const date = new Date(timestamp);\n const time = date.toLocaleTimeString('en-US', {\n hour12: false,\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n });\n const ms = String(date.getMilliseconds()).padStart(3, '0');\n return `${time}.${ms}`;\n}\n\nfunction getEventColor(type: string): string {\n if (type === 'error' || type === 'failed') return 'text-red-400';\n if (type === 'completed') return 'text-green-400';\n if (type === 'status-change') return 'text-cyan-400';\n if (type === 'progress') return 'text-blue-400';\n if (type === 'loading') return 'text-yellow-400';\n return 'text-gray-400';\n}\n\nfunction formatEventData(data: unknown): string {\n if (data === null || data === undefined) return '—';\n if (typeof data === 'string') return data;\n if (typeof data === 'boolean') return data ? 'true' : 'false';\n if (typeof data === 'object') {\n try {\n return JSON.stringify(data);\n } catch {\n return String(data);\n }\n }\n return String(data);\n}\n","/**\n * NetworkLog - Display API requests and responses\n *\n * Shows a list of HTTP requests made by the SDK with:\n * - Method and URL\n * - Status code and duration\n * - Request payload and response data\n * - Error information for failed requests\n */\n\nimport {\n AlertCircle,\n CheckCircle,\n ChevronDown,\n ChevronRight,\n Clock,\n Loader2,\n} from 'lucide-react';\nimport { useState } from 'react';\n\nimport type { NetworkLogEntry } from '../types';\n\ninterface NetworkLogProps {\n /** Network log entries */\n entries: NetworkLogEntry[];\n\n /** Clear network log callback */\n onClear: () => void;\n\n /** Maximum height for scrolling */\n maxHeight?: string;\n}\n\nexport function NetworkLog({\n entries,\n onClear,\n maxHeight = '400px',\n}: NetworkLogProps) {\n const [expandedIds, setExpandedIds] = useState<Set<string>>(new Set());\n\n const toggleExpand = (id: string) => {\n setExpandedIds((prev) => {\n const next = new Set(prev);\n if (next.has(id)) {\n next.delete(id);\n } else {\n next.add(id);\n }\n return next;\n });\n };\n\n if (entries.length === 0) {\n return (\n <div className=\"flex flex-col items-center justify-center py-8 text-gray-500 dark:text-gray-400\">\n <Clock className=\"w-8 h-8 mb-2 opacity-50\" />\n <p className=\"text-sm\">No API requests yet</p>\n <p className=\"text-xs opacity-75 mt-1\">\n Requests will appear here when you use SDK methods\n </p>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col h-full\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-3 py-2 border-b border-gray-200 dark:border-gray-700\">\n <span className=\"text-xs font-medium text-gray-600 dark:text-gray-400\">\n {entries.length} request{entries.length !== 1 ? 's' : ''}\n </span>\n <button\n onClick={onClear}\n className=\"text-xs text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200\"\n >\n Clear\n </button>\n </div>\n\n {/* Entries List */}\n <div className=\"flex-1 overflow-y-auto\" style={{ maxHeight }}>\n {entries.map((entry) => (\n <NetworkEntry\n key={entry.request.id}\n entry={entry}\n isExpanded={expandedIds.has(entry.request.id)}\n onToggle={() => {\n toggleExpand(entry.request.id);\n }}\n />\n ))}\n </div>\n </div>\n );\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Network Entry Component\n// ─────────────────────────────────────────────────────────────────\n\ninterface NetworkEntryProps {\n entry: NetworkLogEntry;\n isExpanded: boolean;\n onToggle: () => void;\n}\n\nfunction NetworkEntry({ entry, isExpanded, onToggle }: NetworkEntryProps) {\n const { request, response, isPending, isFailed } = entry;\n\n // Method color\n const methodColor =\n {\n GET: 'text-emerald-600 dark:text-emerald-400',\n POST: 'text-blue-600 dark:text-blue-400',\n PUT: 'text-amber-600 dark:text-amber-400',\n DELETE: 'text-red-600 dark:text-red-400',\n PATCH: 'text-purple-600 dark:text-purple-400',\n }[request.method] || 'text-gray-600 dark:text-gray-400';\n\n // Status indicator\n const StatusIcon = isPending\n ? () => <Loader2 className=\"w-3.5 h-3.5 animate-spin text-blue-500\" />\n : isFailed\n ? () => <AlertCircle className=\"w-3.5 h-3.5 text-red-500\" />\n : () => <CheckCircle className=\"w-3.5 h-3.5 text-emerald-500\" />;\n\n // Extract path from URL\n const urlPath = (() => {\n try {\n const url = new URL(request.url, 'http://localhost');\n return url.pathname + url.search;\n } catch {\n return request.url;\n }\n })();\n\n return (\n <div\n className={`border-b border-gray-100 dark:border-gray-700/50 ${isFailed ? 'bg-red-50/50 dark:bg-red-900/10' : ''}`}\n >\n {/* Entry Header */}\n <button\n onClick={onToggle}\n className=\"w-full flex items-center gap-2 px-3 py-2 text-left hover:bg-gray-50 dark:hover:bg-gray-700/30 transition-colors\"\n >\n {isExpanded ? (\n <ChevronDown className=\"w-3.5 h-3.5 text-gray-400 flex-shrink-0\" />\n ) : (\n <ChevronRight className=\"w-3.5 h-3.5 text-gray-400 flex-shrink-0\" />\n )}\n\n <StatusIcon />\n\n <span\n className={`text-xs font-mono font-bold ${methodColor} w-10 flex-shrink-0`}\n >\n {request.method}\n </span>\n\n <span className=\"flex-1 text-xs font-mono text-gray-700 dark:text-gray-300 truncate\">\n {urlPath}\n </span>\n\n {response && (\n <>\n <span\n className={`text-xs font-mono ${isFailed ? 'text-red-600 dark:text-red-400' : 'text-gray-500 dark:text-gray-400'}`}\n >\n {response.status}\n </span>\n <span className=\"text-xs text-gray-400 dark:text-gray-500\">\n {response.duration}ms\n </span>\n </>\n )}\n\n {request.source && (\n <span className=\"text-[10px] px-1.5 py-0.5 bg-gray-100 dark:bg-gray-700 text-gray-500 dark:text-gray-400 rounded\">\n {request.source}\n </span>\n )}\n </button>\n\n {/* Expanded Details */}\n {isExpanded && (\n <div className=\"px-3 pb-3 space-y-2\">\n {/* Request */}\n <div>\n <h4\n style={{ fontSize: '10px', lineHeight: '14px' }}\n className=\"font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-1\"\n >\n Request\n </h4>\n <div className=\"bg-gray-50 dark:bg-gray-800 rounded p-2 overflow-x-auto max-w-full\">\n {request.payload ? (\n <pre\n style={{ fontSize: '11px', lineHeight: '16px' }}\n className=\"text-gray-700 dark:text-gray-300 whitespace-pre-wrap break-all font-mono m-0\"\n >\n {JSON.stringify(request.payload, null, 2)}\n </pre>\n ) : (\n <span\n style={{ fontSize: '11px' }}\n className=\"text-gray-400 italic\"\n >\n No payload\n </span>\n )}\n </div>\n </div>\n\n {/* Response */}\n {response && (\n <div>\n <h4\n style={{ fontSize: '10px', lineHeight: '14px' }}\n className=\"font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-1\"\n >\n Response\n {response.error && (\n <span className=\"text-red-500 ml-2\">Error</span>\n )}\n </h4>\n <div\n className={`rounded p-2 overflow-x-auto max-w-full ${isFailed ? 'bg-red-50 dark:bg-red-900/20' : 'bg-gray-50 dark:bg-gray-800'}`}\n >\n {response.error ? (\n <pre\n style={{ fontSize: '11px', lineHeight: '16px' }}\n className=\"text-red-600 dark:text-red-400 whitespace-pre-wrap break-all font-mono m-0\"\n >\n {response.error}\n </pre>\n ) : response.data ? (\n <pre\n style={{ fontSize: '11px', lineHeight: '16px' }}\n className=\"text-gray-700 dark:text-gray-300 whitespace-pre-wrap break-all font-mono m-0\"\n >\n {JSON.stringify(response.data, null, 2)}\n </pre>\n ) : (\n <span\n style={{ fontSize: '11px' }}\n className=\"text-gray-400 italic\"\n >\n No data\n </span>\n )}\n </div>\n </div>\n )}\n\n {/* Pending indicator */}\n {isPending && (\n <div className=\"flex items-center gap-2 text-xs text-blue-600 dark:text-blue-400\">\n <Loader2 className=\"w-3 h-3 animate-spin\" />\n <span>Waiting for response...</span>\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n","/**\n * ReducerLog - Redux DevTools-style action log\n *\n * Shows dispatched actions with before/after state diffs.\n *\n * @module sdk-devtools/components/ReducerLog\n */\n\nimport { Activity, ChevronDown, ChevronRight, Trash2 } from 'lucide-react';\nimport { useState } from 'react';\n\nimport type { ReducerLogEntry } from '../types';\n\nexport interface ReducerLogProps {\n /** Log entries to display */\n logs: ReducerLogEntry[];\n\n /** Callback to clear logs */\n onClear: () => void;\n\n /** Custom class name */\n className?: string;\n}\n\n/**\n * Reducer Log Component\n *\n * Displays reducer actions in a time-ordered list with expandable details.\n */\nexport function ReducerLog({ logs, onClear, className = '' }: ReducerLogProps) {\n return (\n <div className={`h-full flex flex-col ${className}`}>\n {/* Header */}\n <div className=\"flex items-center justify-between px-3 py-1.5 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800\">\n <div className=\"flex items-center gap-2 text-xs text-gray-600 dark:text-gray-400\">\n <Activity className=\"w-3.5 h-3.5\" />\n <span>Action Log</span>\n {logs.length > 0 && (\n <span className=\"px-1.5 py-0.5 bg-gray-200 dark:bg-gray-700 rounded text-[10px]\">\n {logs.length} actions\n </span>\n )}\n </div>\n\n {logs.length > 0 && (\n <button\n onClick={onClear}\n className=\"flex items-center gap-1 text-[10px] text-gray-500 hover:text-gray-700 dark:hover:text-gray-300 transition-colors\"\n >\n <Trash2 className=\"w-3 h-3\" />\n Clear\n </button>\n )}\n </div>\n\n {/* Log List */}\n <div className=\"flex-1 overflow-y-auto\">\n {logs.length === 0 ? (\n <div className=\"text-gray-400 dark:text-gray-600 text-center py-4 text-xs\">\n <p>Reducer actions will appear here...</p>\n </div>\n ) : (\n <div className=\"divide-y divide-gray-200 dark:divide-gray-800\">\n {logs.map((log) => (\n <LogEntry key={log.id} log={log} />\n ))}\n </div>\n )}\n </div>\n </div>\n );\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Log Entry Component\n// ─────────────────────────────────────────────────────────────────\n\nfunction LogEntry({ log }: { log: ReducerLogEntry }) {\n const [isExpanded, setIsExpanded] = useState(false);\n\n return (\n <div className=\"text-xs\">\n <button\n onClick={() => {\n setIsExpanded(!isExpanded);\n }}\n className=\"w-full flex items-center gap-2 px-3 py-2 hover:bg-gray-100 dark:hover:bg-gray-800/50 transition-colors\"\n >\n {isExpanded ? (\n <ChevronDown className=\"w-3 h-3 text-gray-400 dark:text-gray-500\" />\n ) : (\n <ChevronRight className=\"w-3 h-3 text-gray-400 dark:text-gray-500\" />\n )}\n <span className=\"text-gray-400 dark:text-gray-600 flex-shrink-0 font-mono\">\n {formatTime(log.timestamp)}\n </span>\n <span className=\"text-cyan-600 dark:text-cyan-400 font-medium\">\n {log.action.type}\n </span>\n {log.action.payload !== undefined && (\n <span className=\"text-gray-500 truncate\">\n {formatPayload(log.action.payload)}\n </span>\n )}\n </button>\n\n {isExpanded && (\n <div className=\"px-3 pb-3 space-y-2\">\n {/* Action payload */}\n {log.action.payload !== undefined && (\n <div>\n <div className=\"text-[10px] text-gray-500 mb-1\">Payload</div>\n <pre className=\"p-2 bg-gray-100 dark:bg-gray-800 rounded text-[10px] font-mono text-amber-600 dark:text-yellow-300 overflow-x-auto\">\n {JSON.stringify(log.action.payload, null, 2)}\n </pre>\n </div>\n )}\n\n {/* State diff */}\n <div className=\"grid grid-cols-2 gap-2\">\n <div>\n <div className=\"text-[10px] text-gray-500 mb-1\">Before</div>\n <pre className=\"p-2 bg-gray-100 dark:bg-gray-800 rounded text-[10px] font-mono text-gray-600 dark:text-gray-400 overflow-x-auto max-h-32 overflow-y-auto\">\n {JSON.stringify(log.prevState, null, 2)}\n </pre>\n </div>\n <div>\n <div className=\"text-[10px] text-gray-500 mb-1\">After</div>\n <pre className=\"p-2 bg-gray-100 dark:bg-gray-800 rounded text-[10px] font-mono text-green-600 dark:text-green-400 overflow-x-auto max-h-32 overflow-y-auto\">\n {JSON.stringify(log.nextState, null, 2)}\n </pre>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Utilities\n// ─────────────────────────────────────────────────────────────────\n\nfunction formatTime(timestamp: number): string {\n const date = new Date(timestamp);\n return date.toLocaleTimeString('en-US', {\n hour12: false,\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n });\n}\n\nfunction formatPayload(payload: unknown): string {\n if (payload === null || payload === undefined) return '';\n if (typeof payload === 'string') return `\"${payload}\"`;\n if (typeof payload === 'object') {\n try {\n const str = JSON.stringify(payload);\n return str.length > 50 ? str.slice(0, 50) + '...' : str;\n } catch {\n return String(payload);\n }\n }\n return String(payload);\n}\n","/**\n * StateInspector - Debug panel for inspecting state objects\n *\n * Displays state in an expandable JSON tree with syntax highlighting.\n * Supports copy-to-clipboard and collapsible sections.\n *\n * @module sdk-devtools/components/StateInspector\n */\n\nimport { Check, ChevronDown, ChevronRight, Copy } from 'lucide-react';\nimport { useCallback, useState } from 'react';\n\nexport interface StateInspectorProps {\n /** State object to inspect */\n state: Record<string, unknown>;\n\n /** Optional title */\n title?: string;\n\n /** Initial expansion depth (default: 2) */\n defaultExpandDepth?: number;\n\n /** Custom class name */\n className?: string;\n}\n\n/**\n * State Inspector Component\n *\n * Renders a collapsible JSON tree viewer with syntax highlighting.\n */\nexport function StateInspector({\n state,\n title = 'State',\n defaultExpandDepth = 2,\n className = '',\n}: StateInspectorProps) {\n const [isExpanded, setIsExpanded] = useState(true);\n const [copied, setCopied] = useState(false);\n\n const handleCopy = useCallback(async () => {\n try {\n await navigator.clipboard.writeText(JSON.stringify(state, null, 2));\n setCopied(true);\n setTimeout(() => {\n setCopied(false);\n }, 2000);\n } catch (err) {\n console.error('Failed to copy:', err);\n }\n }, [state]);\n\n return (\n <div\n className={`bg-gray-50 dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden h-full flex flex-col ${className}`}\n >\n {/* Header */}\n <div className=\"flex-shrink-0 flex items-center justify-between px-3 py-2 bg-gray-100 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700\">\n <button\n onClick={() => {\n setIsExpanded(!isExpanded);\n }}\n className=\"flex items-center gap-2 text-sm font-medium text-gray-700 dark:text-gray-200 hover:text-gray-900 dark:hover:text-white\"\n >\n {isExpanded ? (\n <ChevronDown className=\"w-4 h-4\" />\n ) : (\n <ChevronRight className=\"w-4 h-4\" />\n )}\n {title}\n </button>\n <button\n onClick={() => {\n void handleCopy();\n }}\n className=\"flex items-center gap-1 text-xs text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 transition-colors\"\n title=\"Copy state as JSON\"\n >\n {copied ? (\n <>\n <Check className=\"w-3 h-3 text-green-500 dark:text-green-400\" />\n <span className=\"text-green-500 dark:text-green-400\">Copied</span>\n </>\n ) : (\n <>\n <Copy className=\"w-3 h-3\" />\n Copy\n </>\n )}\n </button>\n </div>\n\n {/* Content */}\n {isExpanded && (\n <div className=\"p-3 flex-1 overflow-auto\">\n <StateTree value={state} defaultExpandDepth={defaultExpandDepth} />\n </div>\n )}\n </div>\n );\n}\n\n// ─────────────────────────────────────────────────────────────────\n// State Tree Component (recursive JSON viewer)\n// ─────────────────────────────────────────────────────────────────\n\ninterface StateTreeProps {\n value: unknown;\n depth?: number;\n keyName?: string;\n defaultExpandDepth?: number;\n}\n\nfunction StateTree({\n value,\n depth = 0,\n keyName,\n defaultExpandDepth = 2,\n}: StateTreeProps) {\n const [isOpen, setIsOpen] = useState(depth < defaultExpandDepth);\n\n const indent = depth * 12;\n const isExpandable = value !== null && typeof value === 'object';\n\n // Render primitive values\n if (!isExpandable) {\n return (\n <div\n className=\"flex items-baseline gap-1 font-mono text-xs\"\n style={{ marginLeft: indent }}\n >\n {keyName && (\n <span className=\"text-purple-600 dark:text-purple-400\">\n {keyName}:\n </span>\n )}\n <ValueDisplay value={value} />\n </div>\n );\n }\n\n // Handle arrays\n if (Array.isArray(value)) {\n if (value.length === 0) {\n return (\n <div className=\"font-mono text-xs\" style={{ marginLeft: indent }}>\n {keyName && (\n <span className=\"text-purple-600 dark:text-purple-400\">\n {keyName}:{' '}\n </span>\n )}\n <span className=\"text-gray-400 dark:text-gray-500\">[]</span>\n </div>\n );\n }\n\n return (\n <div style={{ marginLeft: indent }}>\n <button\n onClick={() => {\n setIsOpen(!isOpen);\n }}\n className=\"flex items-center gap-1 font-mono text-xs hover:bg-gray-200 dark:hover:bg-gray-800 rounded px-1 -ml-1\"\n >\n {isOpen ? (\n <ChevronDown className=\"w-3 h-3 text-gray-400 dark:text-gray-500\" />\n ) : (\n <ChevronRight className=\"w-3 h-3 text-gray-400 dark:text-gray-500\" />\n )}\n {keyName && (\n <span className=\"text-purple-600 dark:text-purple-400\">\n {keyName}:\n </span>\n )}\n <span className=\"text-gray-500\">[{value.length}]</span>\n </button>\n {isOpen && (\n <div className=\"ml-2\">\n {value.map((item, i) => (\n <StateTree\n key={i}\n value={item}\n depth={depth + 1}\n keyName={String(i)}\n defaultExpandDepth={defaultExpandDepth}\n />\n ))}\n </div>\n )}\n </div>\n );\n }\n\n // Handle objects\n const entries = Object.entries(value as Record<string, unknown>);\n if (entries.length === 0) {\n return (\n <div className=\"font-mono text-xs\" style={{ marginLeft: indent }}>\n {keyName && (\n <span className=\"text-purple-600 dark:text-purple-400\">\n {keyName}:{' '}\n </span>\n )}\n <span className=\"text-gray-400 dark:text-gray-500\">{'{}'}</span>\n </div>\n );\n }\n\n return (\n <div style={{ marginLeft: indent }}>\n <button\n onClick={() => {\n setIsOpen(!isOpen);\n }}\n className=\"flex items-center gap-1 font-mono text-xs hover:bg-gray-200 dark:hover:bg-gray-800 rounded px-1 -ml-1\"\n >\n {isOpen ? (\n <ChevronDown className=\"w-3 h-3 text-gray-400 dark:text-gray-500\" />\n ) : (\n <ChevronRight className=\"w-3 h-3 text-gray-400 dark:text-gray-500\" />\n )}\n {keyName && (\n <span className=\"text-purple-600 dark:text-purple-400\">\n {keyName}:\n </span>\n )}\n <span className=\"text-gray-500\">{`{${entries.length}}`}</span>\n </button>\n {isOpen && (\n <div className=\"ml-2\">\n {entries.map(([key, val]) => (\n <StateTree\n key={key}\n value={val}\n depth={depth + 1}\n keyName={key}\n defaultExpandDepth={defaultExpandDepth}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Value Display (colors based on type)\n// ─────────────────────────────────────────────────────────────────\n\nfunction ValueDisplay({ value }: { value: unknown }) {\n if (value === null) {\n return <span className=\"text-gray-400 dark:text-gray-500\">null</span>;\n }\n if (value === undefined) {\n return <span className=\"text-gray-400 dark:text-gray-500\">undefined</span>;\n }\n if (typeof value === 'boolean') {\n return (\n <span className=\"text-blue-600 dark:text-blue-400\">{String(value)}</span>\n );\n }\n if (typeof value === 'number') {\n return <span className=\"text-green-600 dark:text-green-400\">{value}</span>;\n }\n if (typeof value === 'string') {\n // Truncate long strings\n const display = value.length > 50 ? `${value.slice(0, 50)}...` : value;\n return (\n <span className=\"text-amber-600 dark:text-yellow-300\">\"{display}\"</span>\n );\n }\n return (\n <span className=\"text-gray-600 dark:text-gray-400\">{String(value)}</span>\n );\n}\n","/**\n * StatusBadge - Displays current flow status with color coding\n *\n * Shows the action status in a pill/badge format with appropriate colors.\n *\n * @module sdk-devtools/components/StatusBadge\n */\n\nexport interface StatusBadgeProps {\n /** Status string to display */\n status?: string | unknown;\n\n /** Custom class name */\n className?: string;\n}\n\n/**\n * Status Badge Component\n *\n * Displays action status with color coding based on status type.\n */\nexport function StatusBadge({ status, className = '' }: StatusBadgeProps) {\n // Handle undefined/null/non-string status - convert to string safely\n const safeStatus =\n typeof status === 'string' ? status : String(status ?? 'idle');\n\n return (\n <span\n className={`\n inline-flex items-center px-2.5 py-1 rounded-full text-xs font-medium\n ${getStatusColor(safeStatus)}\n ${className}\n `}\n >\n {formatStatus(safeStatus)}\n </span>\n );\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Utilities\n// ─────────────────────────────────────────────────────────────────\n\nfunction getStatusColor(status: string): string {\n const lower = status.toLowerCase();\n\n // Initial/idle states\n if (lower === 'idle' || lower === 'not_created') {\n return 'bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300';\n }\n\n // Success/final states\n if (lower.includes('address_ready') || lower === 'completed') {\n return 'bg-green-100 text-green-700 dark:bg-green-900/50 dark:text-green-300';\n }\n\n // Authorization/waiting states\n if (\n lower.includes('needs') ||\n lower.includes('authorization') ||\n lower.includes('approval')\n ) {\n return 'bg-amber-100 text-amber-700 dark:bg-amber-900/50 dark:text-amber-300';\n }\n\n // Confirming state\n if (lower === 'confirming') {\n return 'bg-blue-100 text-blue-700 dark:bg-blue-900/50 dark:text-blue-300';\n }\n\n // Ready state\n if (lower === 'ready') {\n return 'bg-teal-100 text-teal-700 dark:bg-teal-900/50 dark:text-teal-300';\n }\n\n // Default\n return 'bg-teal-100 text-teal-700 dark:bg-teal-900/50 dark:text-teal-300';\n}\n\nfunction formatStatus(status: string): string {\n // Handle both snake_case and kebab-case\n return status\n .replace(/[_-]/g, ' ')\n .split(' ')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n}\n","/**\n * StepIndicator - Compact horizontal progress showing current flow step\n *\n * Shows flow steps with visual indicators for completed, current, and upcoming steps.\n *\n * @module sdk-devtools/components/StepIndicator\n */\n\nimport { Check } from 'lucide-react';\n\nimport type { FlowStep } from '../types';\n\n/**\n * Simple step definition (minimal required fields)\n */\nexport interface SimpleStep {\n id: string;\n label: string;\n}\n\nexport interface StepIndicatorProps {\n /** Steps to display - can be simple { id, label } or full FlowStep */\n steps: SimpleStep[] | FlowStep[];\n\n /** Current step index (0-based) */\n currentStep: number;\n\n /** Custom class name */\n className?: string;\n}\n\n/**\n * Step Indicator Component\n *\n * Horizontal progress indicator showing completed, current, and upcoming steps.\n * Uses inline styles for sizing to avoid Tailwind v4 --spacing variable issues.\n * Steps have equal widths to align with the progress bar above.\n */\nexport function StepIndicator({\n steps,\n currentStep,\n className = '',\n}: StepIndicatorProps) {\n return (\n <div\n className={`flex ${className}`}\n style={{\n width: '100%',\n }}\n >\n {steps.map((step, index) => {\n const isCompleted = index < currentStep;\n const isCurrent = index === currentStep;\n const isLast = index === steps.length - 1;\n\n // Determine colors for circle\n const circleStyles: React.CSSProperties = {\n width: '28px',\n height: '28px',\n minWidth: '28px',\n minHeight: '28px',\n borderRadius: '6px', // Slightly rounded corners\n };\n\n if (isCompleted) {\n circleStyles.backgroundColor = '#22c55e'; // green-500\n circleStyles.color = 'white';\n } else if (isCurrent) {\n circleStyles.backgroundColor = 'var(--lombard-green, #00E676)';\n circleStyles.color = '#111827'; // gray-900\n circleStyles.fontWeight = 'bold';\n } else {\n circleStyles.backgroundColor = '#e5e7eb'; // gray-200\n circleStyles.color = '#6b7280'; // gray-500\n }\n\n return (\n <div\n key={step.id}\n style={{\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n position: 'relative',\n }}\n >\n {/* Connector line - positioned absolutely */}\n {!isLast && (\n <div\n style={{\n position: 'absolute',\n top: '14px', // Half of circle height (28/2)\n left: '50%',\n right: '-50%',\n height: '2px',\n backgroundColor: isCompleted ? '#22c55e' : '#e5e7eb',\n zIndex: 0,\n }}\n />\n )}\n\n {/* Step square with rounded corners */}\n <div\n className=\"flex items-center justify-center text-sm font-medium transition-colors\"\n style={{\n ...circleStyles,\n position: 'relative',\n zIndex: 1,\n }}\n >\n {isCompleted ? (\n <Check style={{ width: '16px', height: '16px' }} />\n ) : (\n index + 1\n )}\n </div>\n\n {/* Label below circle */}\n <span\n className=\"text-xs text-center\"\n style={{\n marginTop: '6px',\n color: isCompleted\n ? '#16a34a' // green-600\n : isCurrent\n ? '#111827' // gray-900 (black for active)\n : '#9ca3af', // gray-400\n fontWeight: isCompleted || isCurrent ? 500 : 400,\n }}\n >\n {step.label}\n </span>\n </div>\n );\n })}\n </div>\n );\n}\n\n/**\n * Helper to convert simple step configs to FlowStep format\n */\nexport function createSteps(\n configs: Array<{ id: string; label: string; description?: string }>,\n currentStep: number,\n): FlowStep[] {\n return configs.map((config, index) => ({\n ...config,\n status:\n index < currentStep\n ? 'completed'\n : index === currentStep\n ? 'current'\n : 'pending',\n }));\n}\n","/**\n * useDevTools - React hook for integrating DevTools with SDK actions\n *\n * This is the main hook that developers will use to connect DevTools\n * to their SDK usage. It provides:\n * - Automatic event collection\n * - Action registration\n * - State for DevTools components\n *\n * @module sdk-devtools/hooks/useDevTools\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { DevToolsBridge, getDevToolsBridge } from '../bridge/DevToolsBridge';\nimport type {\n DevToolsConfig,\n DevToolsEvent,\n MonitorableAction,\n RegisteredAction,\n} from '../types';\n\n// ─────────────────────────────────────────────────────────────────\n// Hook Return Type\n// ─────────────────────────────────────────────────────────────────\n\nexport interface UseDevToolsReturn {\n /** All collected events */\n events: DevToolsEvent[];\n\n /** All registered actions */\n actions: Map<string, RegisteredAction>;\n\n /** Current state summary */\n stateSummary: Record<\n string,\n { status: string; isLoading: boolean; hasError: boolean }\n >;\n\n /** Register an action for monitoring */\n registerAction: (\n name: string,\n action: MonitorableAction,\n options?: { category?: string },\n ) => () => void;\n\n /** Unregister an action */\n unregisterAction: (name: string) => void;\n\n /** Clear all events */\n clearEvents: () => void;\n\n /** Clear all actions */\n clearActions: () => void;\n\n /** The underlying bridge instance */\n bridge: DevToolsBridge;\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Main Hook\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * React hook for DevTools integration\n *\n * @example Basic usage\n * ```tsx\n * function MyComponent() {\n * const { events, registerAction, clearEvents } = useDevTools();\n *\n * useEffect(() => {\n * const stake = sdk.btc.stake({ destChain: Chain.ETHEREUM, assetOut: AssetId.LBTC });\n * const unregister = registerAction('stake', stake);\n *\n * return unregister;\n * }, []);\n *\n * return (\n * <DevToolsPanel\n * events={events}\n * onClearEvents={clearEvents}\n * />\n * );\n * }\n * ```\n *\n * @example With useAction helper\n * ```tsx\n * function MyComponent() {\n * const { registerAction } = useDevTools();\n *\n * const stake = useAction(() => {\n * const action = sdk.btc.stake({ ... });\n * registerAction('stake', action);\n * return action;\n * }, []);\n *\n * // stake is automatically monitored\n * }\n * ```\n */\nexport function useDevTools(config?: DevToolsConfig): UseDevToolsReturn {\n // Use global bridge or create local one\n const bridgeRef = useRef<DevToolsBridge | null>(null);\n\n if (!bridgeRef.current) {\n bridgeRef.current = config\n ? new DevToolsBridge(config)\n : getDevToolsBridge();\n }\n\n const bridge = bridgeRef.current;\n\n // State for React re-renders\n const [events, setEvents] = useState<DevToolsEvent[]>(() =>\n bridge.getEvents(),\n );\n const [actions, setActions] = useState<Map<string, RegisteredAction>>(() =>\n bridge.getActions(),\n );\n\n // Subscribe to bridge updates\n useEffect(() => {\n const unsubEvent = bridge.onEvent(() => {\n setEvents(bridge.getEvents());\n });\n\n const unsubState = bridge.onStateChange((newActions) => {\n setActions(newActions);\n });\n\n return () => {\n unsubEvent();\n unsubState();\n };\n }, [bridge]);\n\n // Memoized callbacks\n const registerAction = useCallback(\n (\n name: string,\n action: MonitorableAction,\n options?: { category?: string },\n ) => {\n return bridge.registerAction(name, action, options);\n },\n [bridge],\n );\n\n const unregisterAction = useCallback(\n (name: string) => {\n bridge.unregisterAction(name);\n },\n [bridge],\n );\n\n const clearEvents = useCallback(() => {\n bridge.clearEvents();\n setEvents([]);\n }, [bridge]);\n\n const clearActions = useCallback(() => {\n bridge.clearActions();\n setActions(new Map());\n }, [bridge]);\n\n // Compute state summary\n const stateSummary = useMemo(() => bridge.getStateSummary(), [actions]);\n\n return {\n events,\n actions,\n stateSummary,\n registerAction,\n unregisterAction,\n clearEvents,\n clearActions,\n bridge,\n };\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Helper Hook: useMonitoredAction\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * Hook that creates an action and automatically registers it with DevTools\n *\n * @example\n * ```tsx\n * const stake = useMonitoredAction(\n * 'btc-stake',\n * () => sdk.btc.stake({ destChain: Chain.ETHEREUM, assetOut: AssetId.LBTC }),\n * [sdk],\n * );\n * ```\n */\nexport function useMonitoredAction<T extends MonitorableAction>(\n name: string,\n createAction: () => T,\n deps: React.DependencyList,\n): T | null {\n const { registerAction } = useDevTools();\n const [action, setAction] = useState<T | null>(null);\n\n useEffect(() => {\n const newAction = createAction();\n setAction(newAction);\n\n const unregister = registerAction(name, newAction);\n\n return () => {\n unregister();\n setAction(null);\n };\n }, deps);\n\n return action;\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Helper Hook: useActionEvents\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * Hook that subscribes to events from a specific action\n *\n * @example\n * ```tsx\n * const { events, status, isLoading, error } = useActionEvents(stakeAction);\n * ```\n */\nexport function useActionEvents(action: MonitorableAction | null) {\n const [events, setEvents] = useState<DevToolsEvent[]>([]);\n const [status, setStatus] = useState<string>(action?.status ?? 'idle');\n const [isLoading, setIsLoading] = useState(action?.isLoading ?? false);\n const [error, setError] = useState<Error | null>(action?.error ?? null);\n const eventIdRef = useRef(0);\n\n useEffect(() => {\n if (!action) return;\n\n const unsubscribers: Array<() => void> = [];\n\n // Status change\n unsubscribers.push(\n action.on('status-change', (newStatus: unknown) => {\n setStatus(String(newStatus));\n setEvents((prev) => [\n ...prev,\n {\n id: String(++eventIdRef.current),\n type: 'status-change',\n timestamp: Date.now(),\n data: newStatus,\n isSDKEvent: true,\n },\n ]);\n }),\n );\n\n // Loading\n unsubscribers.push(\n action.on('loading', (loading: unknown) => {\n setIsLoading(Boolean(loading));\n setEvents((prev) => [\n ...prev,\n {\n id: String(++eventIdRef.current),\n type: 'loading',\n timestamp: Date.now(),\n data: loading,\n isSDKEvent: true,\n },\n ]);\n }),\n );\n\n // Error\n unsubscribers.push(\n action.on('error', (err: unknown) => {\n setError(err as Error);\n setEvents((prev) => [\n ...prev,\n {\n id: String(++eventIdRef.current),\n type: 'error',\n timestamp: Date.now(),\n data: err,\n isSDKEvent: true,\n },\n ]);\n }),\n );\n\n // Completed\n unsubscribers.push(\n action.on('completed', () => {\n setEvents((prev) => [\n ...prev,\n {\n id: String(++eventIdRef.current),\n type: 'completed',\n timestamp: Date.now(),\n data: null,\n isSDKEvent: true,\n },\n ]);\n }),\n );\n\n // Failed\n unsubscribers.push(\n action.on('failed', () => {\n setEvents((prev) => [\n ...prev,\n {\n id: String(++eventIdRef.current),\n type: 'failed',\n timestamp: Date.now(),\n data: null,\n isSDKEvent: true,\n },\n ]);\n }),\n );\n\n return () => {\n unsubscribers.forEach((unsub) => {\n unsub();\n });\n };\n }, [action]);\n\n const clearEvents = useCallback(() => {\n setEvents([]);\n }, []);\n\n return {\n events,\n status,\n isLoading,\n error,\n isFailed: error !== null,\n clearEvents,\n };\n}\n","/**\n * useMockWallet - Simulated wallet for testing SDK flows\n *\n * Provides mock addresses for exploring SDK without connecting a real wallet.\n *\n * IMPORTANT LIMITATIONS:\n * The mock wallet provides valid addresses for UI exploration and auto-filling\n * recipient fields. However, it CANNOT perform actual wallet operations:\n * - EIP-712 signature signing (fee authorization)\n * - Transaction signing\n * - Message signing\n *\n * For full flow testing, connect a real wallet.\n *\n * @module sdk-devtools/hooks/useMockWallet\n */\n\nimport { useCallback, useMemo, useState } from 'react';\n\nimport type { MockAddresses, MockWalletState } from '../types';\n\n// ─────────────────────────────────────────────────────────────────\n// Mock Addresses\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * Deterministic mock addresses for consistent testing.\n * Uses well-known addresses that are valid for each chain type.\n */\nexport const MOCK_ADDRESSES: MockAddresses = {\n // Vitalik's address (properly checksummed)\n evm: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',\n // Valid mainnet bitcoin address\n bitcoin: 'bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh',\n // Valid Solana address\n solana: 'DRpbCBMxVnDK7maPMxTm9dRYNLGhPEYALmJY9VvUdWTm',\n // Valid Sui address\n sui: '0x7d20dcdb2bca4f508ea9613994683eb4e76e9cc555c8e2d4f8362e10e4eca31b',\n // Valid Starknet address\n starknet:\n '0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',\n};\n\n// ─────────────────────────────────────────────────────────────────\n// Limitations\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * Mock wallet limitations - clearly document what it can/cannot do\n */\nexport const MOCK_WALLET_LIMITATIONS = {\n /** Cannot sign transactions */\n cannotSign: true,\n\n /** Steps that work with mock wallet */\n supportedSteps: ['Create', 'Prepare'] as const,\n\n /** Steps that require real wallet */\n unsupportedSteps: ['Authorize', 'Sign', 'Execute'] as const,\n\n /** User-friendly message */\n message:\n 'Mock wallet cannot sign transactions. Connect a real wallet for full flow.',\n\n /** Short message for badges */\n shortMessage: 'Cannot sign - connect real wallet',\n};\n\n// ─────────────────────────────────────────────────────────────────\n// Storage Key\n// ─────────────────────────────────────────────────────────────────\n\nconst STORAGE_KEY = 'lombard-devtools-mock-wallet';\n\n// ─────────────────────────────────────────────────────────────────\n// Hook\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * Hook for managing mock wallet state\n *\n * Provides a mock wallet that auto-fills addresses but cannot sign transactions.\n * State is persisted in localStorage.\n *\n * @example\n * ```tsx\n * const mockWallet = useMockWallet();\n *\n * if (!connectedWallet && !mockWallet.isEnabled) {\n * return <button onClick={mockWallet.enable}>Use Mock Wallet</button>;\n * }\n *\n * const address = connectedWallet?.address ?? mockWallet.address;\n * ```\n */\nexport function useMockWallet(): MockWalletState {\n // Load initial state from localStorage\n const [isEnabled, setIsEnabled] = useState(() => {\n if (typeof window === 'undefined') return false;\n return localStorage.getItem(STORAGE_KEY) === 'true';\n });\n\n const [chainId, setChainId] = useState(1); // Default to Ethereum mainnet\n\n const enable = useCallback(() => {\n setIsEnabled(true);\n if (typeof window !== 'undefined') {\n localStorage.setItem(STORAGE_KEY, 'true');\n }\n }, []);\n\n const disable = useCallback(() => {\n setIsEnabled(false);\n if (typeof window !== 'undefined') {\n localStorage.setItem(STORAGE_KEY, 'false');\n }\n }, []);\n\n const toggle = useCallback(() => {\n setIsEnabled((prev) => {\n const newValue = !prev;\n if (typeof window !== 'undefined') {\n localStorage.setItem(STORAGE_KEY, String(newValue));\n }\n return newValue;\n });\n }, []);\n\n const setChain = useCallback((newChainId: number) => {\n setChainId(newChainId);\n }, []);\n\n const getAddress = useCallback((chainType: keyof MockAddresses): string => {\n return MOCK_ADDRESSES[chainType];\n }, []);\n\n // Memoize the return object\n return useMemo(\n () => ({\n isEnabled,\n address: MOCK_ADDRESSES.evm, // Default to EVM\n chainId,\n canSign: false, // Mock wallet cannot sign - always false\n enable,\n disable,\n toggle,\n setChain,\n getAddress,\n }),\n [isEnabled, chainId, enable, disable, toggle, setChain, getAddress],\n );\n}\n\n// ─────────────────────────────────────────────────────────────────\n// Utility Functions\n// ─────────────────────────────────────────────────────────────────\n\n/**\n * Get mock address for a chain type\n */\nexport function getMockAddress(chainType: keyof MockAddresses): string {\n return MOCK_ADDRESSES[chainType];\n}\n\n/**\n * Check if a step requires a real wallet\n */\nexport function requiresRealWallet(stepLabel: string): boolean {\n const lower = stepLabel.toLowerCase();\n return (\n lower.includes('authorize') ||\n lower.includes('sign') ||\n lower.includes('execute')\n );\n}\n"],"mappings":"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","names":["Activity","Terminal","useMemo","useState","jsx","useState","jsx","jsxs","ChevronDown","ChevronRight","Trash2","useState","jsx","jsxs","formatTime","ChevronDown","ChevronRight","useCallback","useState","Fragment","jsx","jsxs","jsx","jsxs","useState","useMemo","Terminal","Activity","jsx","Check","jsx","jsxs","useCallback","useEffect","useMemo","useState","useState","useEffect","useCallback","useMemo","useCallback","useMemo","useState"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lombard.finance/sdk-devtools",
|
|
3
|
+
"version": "0.1.0-canary-2.10",
|
|
4
|
+
"description": "Developer tools for the Lombard SDK - debugging, inspection, and testing utilities",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"LICENSE"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsup",
|
|
21
|
+
"dev": "tsup --watch",
|
|
22
|
+
"test": "vitest run",
|
|
23
|
+
"test:watch": "vitest",
|
|
24
|
+
"typecheck": "tsc --noEmit",
|
|
25
|
+
"lint": "eslint src --ext .ts,.tsx",
|
|
26
|
+
"clean": "rm -rf dist"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"lucide-react": "^0.454.0"
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"@lombard.finance/sdk": "*",
|
|
33
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
34
|
+
"react-dom": "^18.0.0 || ^19.0.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@testing-library/dom": "^10.4.0",
|
|
38
|
+
"@testing-library/react": "^16.0.1",
|
|
39
|
+
"@types/react": "^18.3.12",
|
|
40
|
+
"@types/react-dom": "^18.3.1",
|
|
41
|
+
"jsdom": "^25.0.1",
|
|
42
|
+
"react": "^18.3.1",
|
|
43
|
+
"react-dom": "^18.3.1",
|
|
44
|
+
"tsup": "^8.3.5",
|
|
45
|
+
"typescript": "^5.5.4",
|
|
46
|
+
"vitest": "^2.1.4"
|
|
47
|
+
},
|
|
48
|
+
"homepage": "https://docs.lombard.finance",
|
|
49
|
+
"bugs": {
|
|
50
|
+
"url": "https://github.com/lombard-finance/sdk/issues"
|
|
51
|
+
},
|
|
52
|
+
"publishConfig": {
|
|
53
|
+
"access": "public"
|
|
54
|
+
},
|
|
55
|
+
"repository": {
|
|
56
|
+
"type": "git",
|
|
57
|
+
"url": "https://github.com/lombard-finance/sdk.git",
|
|
58
|
+
"directory": "packages/sdk-devtools"
|
|
59
|
+
},
|
|
60
|
+
"keywords": [
|
|
61
|
+
"lombard",
|
|
62
|
+
"sdk",
|
|
63
|
+
"devtools",
|
|
64
|
+
"debugging",
|
|
65
|
+
"bitcoin",
|
|
66
|
+
"lbtc",
|
|
67
|
+
"staking"
|
|
68
|
+
],
|
|
69
|
+
"license": "MIT"
|
|
70
|
+
}
|