@fiber-pay/react 0.2.4 → 0.2.6

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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/connect-button.tsx","../src/use-fiber-node.ts","../src/fiber-pay-quick-card.tsx","../src/use-fiber-payment.ts","../src/node-info-panel.tsx"],"sourcesContent":["export type {\n BrowserNodeState,\n FiberBrowserNodeConfig,\n FiberWasmFactory,\n NodeInfoResult,\n PasskeySupportReason,\n} from '@fiber-pay/sdk/browser';\nexport {\n ChannelState,\n ConfigBuilder,\n ckbHash,\n ckbToShannons,\n derivePublicKey,\n FiberBrowserNode,\n FiberRpcError,\n formatShannonsAsCkb,\n fromHex,\n getLockBalanceShannons,\n PasskeyCredentialProvider,\n PasswordCredentialProvider,\n RawKeyCredentialProvider,\n scriptToAddress,\n shannonsToCkb,\n toHex,\n} from '@fiber-pay/sdk/browser';\nexport type {\n ConnectButtonConnectedDropdownContext,\n ConnectButtonProps,\n ConnectStrategy,\n} from './connect-button.js';\nexport { ConnectButton } from './connect-button.js';\nexport type { FiberPayQuickCardProps } from './fiber-pay-quick-card.js';\nexport { FiberPayQuickCard } from './fiber-pay-quick-card.js';\nexport type { NodeInfoPanelProps } from './node-info-panel.js';\nexport { NodeInfoPanel } from './node-info-panel.js';\nexport type { UseFiberNodeOptions, UseFiberNodeResult } from './use-fiber-node.js';\nexport { useFiberNode } from './use-fiber-node.js';\nexport type { UseFiberPaymentResult } from './use-fiber-payment.js';\nexport { useFiberPayment } from './use-fiber-payment.js';\n","/**\n * ConnectButton — A unified connect/disconnect button for Fiber browser nodes.\n *\n * Supports three usage modes:\n * 1. **Standalone** — Internally manages `useFiberNode`. Simplest API.\n * 2. **External hook** — Accepts a pre-existing `useFiberNode` result via the `fiber` prop,\n * so sibling components can share the same node instance.\n * 3. **Auto-detection** — If `fiber` is provided, uses it; otherwise creates its own.\n *\n * @example Standalone\n * ```tsx\n * <ConnectButton network=\"testnet\" strategy=\"passkey\" onConnect={(node) => setNode(node)} />\n * ```\n *\n * @example External hook\n * ```tsx\n * const fiber = useFiberNode({ network: \"testnet\" });\n * <ConnectButton fiber={fiber} strategy=\"passkey\" />\n * ```\n */\n\nimport type { FiberBrowserNode, FiberWasmFactory, NodeInfoResult } from '@fiber-pay/sdk/browser';\nimport {\n type CSSProperties,\n type ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport type { UseFiberNodeOptions, UseFiberNodeResult } from './use-fiber-node.js';\nimport { useFiberNode } from './use-fiber-node.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/** Credential strategy the ConnectButton should use */\nexport type ConnectStrategy = 'passkey' | 'password' | 'rawKey' | 'auto';\n\nexport interface ConnectButtonProps {\n /** Network to connect to. Required in standalone mode; ignored when `fiber` is provided. */\n network?: 'testnet' | 'mainnet';\n\n /**\n * Pre-existing hook result from `useFiberNode()`.\n * When provided, the button delegates to this instead of creating its own hook.\n */\n fiber?: UseFiberNodeResult;\n\n /** Credential strategy. Defaults to `\"auto\"`. */\n strategy?: ConnectStrategy;\n\n /** Password for the \"password\" strategy. */\n password?: string;\n\n /** Raw Fiber key (32 bytes) for the \"rawKey\" strategy. */\n rawKey?: Uint8Array;\n\n /** Raw CKB secret key (32 bytes) for the \"rawKey\" strategy (optional). */\n rawCkbKey?: Uint8Array;\n\n /** Wallet identifier for IndexedDB isolation. */\n walletId?: string;\n\n /** Display name for passkey registration. */\n passkeyUsername?: string;\n\n /** Optional WASM factory override. */\n wasmFactory?: FiberWasmFactory;\n\n /** Additional node config. */\n nodeConfig?: UseFiberNodeOptions['nodeConfig'];\n\n /** Additional CSS class name(s) for the root container. */\n className?: string;\n\n /** Inline styles for the root container. */\n style?: CSSProperties;\n\n /** Inline styles for the connected dropdown container. */\n dropdownStyle?: CSSProperties;\n\n /**\n * Optional custom renderer for the connected dropdown content.\n * Use this to render project-specific controls (for example peer/channel actions)\n * while reusing the SDK's connect/disconnect lifecycle logic via the provided context.\n * When set, this replaces the default dropdown content, so custom renderers must\n * render their own disconnect UI if they want to expose disconnect actions.\n */\n renderConnectedDropdown?: (context: ConnectButtonConnectedDropdownContext) => ReactNode;\n\n /**\n * Called when the node reaches the \"running\" state.\n * Receives the `FiberBrowserNode` instance and its `NodeInfoResult`.\n */\n onConnect?: (node: FiberBrowserNode, nodeInfo: NodeInfoResult) => void;\n\n /** Called after the node is stopped. */\n onDisconnect?: () => void;\n\n /** Called when an error occurs. */\n onError?: (error: string) => void;\n}\n\nexport interface ConnectButtonConnectedDropdownContext {\n fiber: UseFiberNodeResult;\n closeDropdown: () => void;\n disconnect: () => Promise<void>;\n}\n\n// =============================================================================\n// Helpers\n// =============================================================================\n\nfunction truncateNodeId(id: string): string {\n if (id.length <= 16) return id;\n return `${id.slice(0, 8)}…${id.slice(-4)}`;\n}\n\n// =============================================================================\n// CSS (inline defaults using CSS custom properties)\n// =============================================================================\n\nconst styles = {\n root: {\n position: 'relative',\n display: 'inline-flex',\n alignItems: 'center',\n gap: '0.5rem',\n fontFamily: 'system-ui, -apple-system, sans-serif',\n } satisfies CSSProperties,\n\n button: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '0.5rem',\n padding: '0.5rem 1.25rem',\n fontSize: '0.875rem',\n fontWeight: 600,\n borderRadius: '9999px',\n border: 'none',\n cursor: 'pointer',\n transition: 'background-color 0.15s, opacity 0.15s',\n lineHeight: 1.4,\n } satisfies CSSProperties,\n\n connectButton: {\n backgroundColor: 'var(--fpay-accent, #6366f1)',\n color: 'var(--fpay-accent-fg, #fff)',\n } satisfies CSSProperties,\n\n connectedButton: {\n backgroundColor: 'var(--fpay-accent-subtle, rgba(99,102,241,0.12))',\n color: 'var(--fpay-accent, #6366f1)',\n border: '1px solid var(--fpay-accent-border, rgba(99,102,241,0.35))',\n } satisfies CSSProperties,\n\n disabledButton: {\n opacity: 0.6,\n cursor: 'not-allowed',\n } satisfies CSSProperties,\n\n statusDot: {\n display: 'inline-block',\n width: '0.5rem',\n height: '0.5rem',\n borderRadius: '50%',\n backgroundColor: 'var(--fpay-accent, #6366f1)',\n } satisfies CSSProperties,\n\n errorText: {\n fontSize: '0.75rem',\n color: 'var(--fpay-error, #ef4444)',\n maxWidth: '220px',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n } satisfies CSSProperties,\n\n dropdown: {\n position: 'absolute',\n right: 0,\n top: '100%',\n marginTop: '0.5rem',\n width: '280px',\n borderRadius: '0.75rem',\n border: '1px solid var(--fpay-border, #e5e7eb)',\n backgroundColor: 'var(--fpay-bg-elevated, #fff)',\n padding: '1rem',\n boxShadow: '0 10px 25px rgba(0,0,0,0.1)',\n zIndex: 100,\n } satisfies CSSProperties,\n\n infoRow: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n padding: '0.375rem 0',\n fontSize: '0.75rem',\n } satisfies CSSProperties,\n\n infoLabel: {\n color: 'var(--fpay-text-secondary, #6b7280)',\n } satisfies CSSProperties,\n\n infoValue: {\n fontFamily: 'ui-monospace, monospace',\n color: 'var(--fpay-text-primary, #111827)',\n } satisfies CSSProperties,\n\n separator: {\n borderTop: '1px solid var(--fpay-border, #e5e7eb)',\n margin: '0.75rem 0',\n } satisfies CSSProperties,\n\n disconnectButton: {\n display: 'flex',\n width: '100%',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '0.625rem 0.75rem',\n fontSize: '0.875rem',\n fontWeight: 600,\n border: '1px solid var(--fpay-border, #e5e7eb)',\n borderRadius: '0.5rem',\n backgroundColor: 'var(--fpay-bg-secondary, #f9fafb)',\n color: 'var(--fpay-text-primary, #111827)',\n cursor: 'pointer',\n transition: 'background-color 0.15s',\n } satisfies CSSProperties,\n\n spinner: {\n animation: 'fpay-spin 1s linear infinite',\n } satisfies CSSProperties,\n};\n\n// Keyframes are injected once via a <style> tag\nconst KEYFRAMES_ID = 'fpay-connect-button-keyframes';\nfunction ensureKeyframes() {\n if (typeof document === 'undefined') return;\n if (document.getElementById(KEYFRAMES_ID)) return;\n const style = document.createElement('style');\n style.id = KEYFRAMES_ID;\n style.textContent = `@keyframes fpay-spin { to { transform: rotate(360deg); } }`;\n document.head.appendChild(style);\n}\n\n// =============================================================================\n// Spinner SVG\n// =============================================================================\n\nfunction Spinner({ size = 16 }: { size?: number }) {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={styles.spinner}\n role=\"img\"\n aria-label=\"Loading\"\n >\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n </svg>\n );\n}\n\n// Chevron SVG for the dropdown toggle\nfunction Chevron({ open }: { open: boolean }) {\n return (\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{ transition: 'transform 0.15s', transform: open ? 'rotate(180deg)' : 'none' }}\n aria-hidden=\"true\"\n >\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n );\n}\n\n// =============================================================================\n// Component\n// =============================================================================\n\nexport function ConnectButton(props: ConnectButtonProps) {\n const {\n network = 'testnet',\n fiber: externalFiber,\n strategy = 'auto',\n password,\n rawKey,\n rawCkbKey,\n walletId,\n passkeyUsername = 'User',\n wasmFactory,\n nodeConfig,\n className,\n style,\n dropdownStyle,\n renderConnectedDropdown,\n onConnect,\n onDisconnect,\n onError,\n } = props;\n\n // --- Hook: internal or external -------------------------------------------\n const internalFiber = useFiberNode({\n network,\n walletId,\n wasmFactory,\n nodeConfig,\n enabled: !externalFiber,\n });\n\n const fiber = externalFiber ?? internalFiber;\n\n const {\n state,\n node,\n nodeInfo,\n error,\n isStarting,\n isRunning,\n isPasskeySupported,\n passkeyUnavailableReason,\n hasPasskeyConfigured,\n createPasskeyAndStart,\n startWithPasskey,\n startWithPassword,\n startWithRawKey,\n stop,\n } = fiber;\n\n // --- Local UI state -------------------------------------------------------\n const [isConnecting, setIsConnecting] = useState(false);\n const [showDropdown, setShowDropdown] = useState(false);\n const [localError, setLocalError] = useState<string | null>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n const effectiveIsStarting = isConnecting || isStarting;\n\n // Inject keyframes on mount\n useEffect(() => ensureKeyframes(), []);\n\n // Click-outside to close dropdown\n useEffect(() => {\n if (!showDropdown) return;\n function handleClickOutside(e: MouseEvent) {\n if (dropdownRef.current && !dropdownRef.current.contains(e.target as Node)) {\n setShowDropdown(false);\n }\n }\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, [showDropdown]);\n\n // Notify parent on connect/disconnect\n const prevRunningRef = useRef(false);\n useEffect(() => {\n if (isRunning && !prevRunningRef.current && node && nodeInfo) {\n onConnect?.(node, nodeInfo);\n }\n if (!isRunning && prevRunningRef.current) {\n onDisconnect?.();\n }\n prevRunningRef.current = isRunning;\n }, [isRunning, node, nodeInfo, onConnect, onDisconnect]);\n\n // Notify parent on error\n useEffect(() => {\n if (error) onError?.(error);\n }, [error, onError]);\n\n // --- Actions --------------------------------------------------------------\n\n const resolvedStrategy =\n strategy === 'auto'\n ? hasPasskeyConfigured && isPasskeySupported\n ? 'passkey'\n : password\n ? 'password'\n : rawKey\n ? 'rawKey'\n : 'passkey'\n : strategy;\n\n const handleConnect = useCallback(async () => {\n setIsConnecting(true);\n setLocalError(null);\n try {\n switch (resolvedStrategy) {\n case 'password':\n if (!password) throw new Error('Password is required for \"password\" strategy');\n await startWithPassword(password);\n break;\n case 'rawKey':\n if (!rawKey) throw new Error('rawKey is required for \"rawKey\" strategy');\n await startWithRawKey(rawKey, rawCkbKey);\n break;\n case 'passkey':\n if (hasPasskeyConfigured) {\n await startWithPasskey();\n } else {\n await createPasskeyAndStart(passkeyUsername);\n }\n break;\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n setLocalError(msg);\n onError?.(msg);\n } finally {\n setIsConnecting(false);\n }\n }, [\n resolvedStrategy,\n password,\n rawKey,\n rawCkbKey,\n passkeyUsername,\n hasPasskeyConfigured,\n startWithPassword,\n startWithPasskey,\n startWithRawKey,\n createPasskeyAndStart,\n onError,\n ]);\n\n const handleDisconnect = useCallback(async () => {\n try {\n await stop();\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n setLocalError(msg);\n onError?.(msg);\n } finally {\n setShowDropdown(false);\n }\n }, [stop, onError]);\n\n const closeDropdown = useCallback(() => {\n setShowDropdown(false);\n }, []);\n\n // --- Render ---------------------------------------------------------------\n\n const hasError = !!(error || localError);\n\n // Determine button content and behaviour\n let buttonLabel: ReactNode;\n let buttonOnClick: (() => void) | undefined;\n let buttonDisabled = false;\n let buttonStyle: CSSProperties;\n\n if (isRunning) {\n buttonLabel = (\n <>\n <span style={styles.statusDot} />\n <span style={{ fontFamily: 'ui-monospace, monospace' }}>\n {nodeInfo?.pubkey ? truncateNodeId(nodeInfo.pubkey) : 'Connected'}\n </span>\n <Chevron open={showDropdown} />\n </>\n );\n buttonOnClick = () => setShowDropdown((s) => !s);\n buttonStyle = { ...styles.button, ...styles.connectedButton };\n } else if (effectiveIsStarting) {\n buttonLabel = (\n <>\n <Spinner />\n Connecting…\n </>\n );\n buttonDisabled = true;\n buttonStyle = { ...styles.button, ...styles.connectButton, ...styles.disabledButton };\n } else {\n // Idle — label depends on strategy\n switch (resolvedStrategy) {\n case 'passkey':\n buttonLabel = hasPasskeyConfigured ? 'Connect with Passkey' : 'Connect via Passkey';\n if (!isPasskeySupported) {\n buttonLabel = 'Passkey unavailable';\n buttonDisabled = true;\n }\n break;\n case 'password':\n buttonLabel = 'Connect';\n break;\n case 'rawKey':\n buttonLabel = 'Connect';\n break;\n }\n buttonOnClick = handleConnect;\n buttonStyle = {\n ...styles.button,\n ...styles.connectButton,\n ...(buttonDisabled ? styles.disabledButton : {}),\n };\n }\n\n return (\n <div className={className} style={{ ...styles.root, ...style }} data-fpay-connect-button=\"\">\n {/* Error / passkey unavailability message */}\n {(hasError ||\n (!isPasskeySupported && passkeyUnavailableReason && resolvedStrategy === 'passkey')) && (\n <span style={styles.errorText}>{error || localError || passkeyUnavailableReason}</span>\n )}\n\n {isRunning ? (\n <div style={{ position: 'relative' }} ref={dropdownRef}>\n <button type=\"button\" onClick={buttonOnClick} style={buttonStyle}>\n {buttonLabel}\n </button>\n\n {showDropdown && (\n <div style={{ ...styles.dropdown, ...dropdownStyle }}>\n {renderConnectedDropdown ? (\n renderConnectedDropdown({\n fiber,\n closeDropdown,\n disconnect: handleDisconnect,\n })\n ) : (\n <>\n {/* Node info */}\n {nodeInfo && (\n <>\n <div style={styles.infoRow}>\n <span style={styles.infoLabel}>Pubkey</span>\n <span style={styles.infoValue}>{truncateNodeId(nodeInfo.pubkey)}</span>\n </div>\n <div style={styles.infoRow}>\n <span style={styles.infoLabel}>State</span>\n <span style={styles.infoValue}>{state}</span>\n </div>\n </>\n )}\n\n <div style={styles.separator} />\n\n {/* Disconnect */}\n <button\n type=\"button\"\n onClick={() => void handleDisconnect()}\n style={styles.disconnectButton}\n >\n <span>Disconnect</span>\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M9 18l6-6-6-6\" />\n </svg>\n </button>\n </>\n )}\n </div>\n )}\n </div>\n ) : (\n <button type=\"button\" onClick={buttonOnClick} disabled={buttonDisabled} style={buttonStyle}>\n {buttonLabel}\n </button>\n )}\n </div>\n );\n}\n","import {\n type BrowserNodeState,\n FiberBrowserNode,\n type FiberBrowserNodeConfig,\n type FiberWasmFactory,\n type NodeInfoResult,\n PasskeyCredentialProvider,\n type PasskeySupportReason,\n type PasskeySupportStatus,\n PasswordCredentialProvider,\n RawKeyCredentialProvider,\n} from '@fiber-pay/sdk/browser';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nexport interface UseFiberNodeOptions {\n network: 'testnet' | 'mainnet';\n walletId?: string;\n nodeConfig?: FiberBrowserNodeConfig['nodeConfig'];\n wasmFactory?: FiberWasmFactory;\n /** If false, suppresses initialization effects (like passkey detection). Default true. */\n enabled?: boolean;\n}\n\nexport interface UseFiberNodeResult {\n state: BrowserNodeState;\n node: FiberBrowserNode | null;\n nodeInfo: NodeInfoResult | null;\n error: string | null;\n /** Whether the node is currently starting (unlocking or starting state) */\n isStarting: boolean;\n /** Whether the node is running and ready for RPC calls */\n isRunning: boolean;\n isPasskeySupported: boolean;\n passkeySupportReason: PasskeySupportReason | null;\n passkeyUnavailableReason: string | null;\n hasPasskeyConfigured: boolean;\n startWithPassword: (password: string) => Promise<void>;\n createPasskeyAndStart: (username?: string) => Promise<void>;\n startWithPasskey: () => Promise<void>;\n startWithRawKey: (fiberKey: Uint8Array, ckbSecretKey?: Uint8Array) => Promise<void>;\n stop: () => Promise<void>;\n}\n\nconst PASSKEY_UNAVAILABLE_REASON_TEXT: Record<\n Exclude<PasskeySupportReason, 'supported'>,\n string\n> = {\n 'window-unavailable': 'Passkey is not available because there is no browser window context.',\n 'insecure-context': 'Passkey requires a secure context (HTTPS or localhost).',\n 'webauthn-unavailable': 'This browser does not provide WebAuthn support for passkeys.',\n 'prf-unsupported': 'This browser or authenticator does not support WebAuthn PRF.',\n unknown: 'Passkey support could not be fully detected in this environment.',\n};\n\nexport function isPasskeyPotentiallySupported(status: PasskeySupportStatus): boolean {\n return status.supported || status.reason === 'unknown';\n}\n\nexport function toPasskeyUnavailableReason(reason: PasskeySupportReason): string | null {\n if (reason === 'supported') {\n return null;\n }\n return PASSKEY_UNAVAILABLE_REASON_TEXT[reason];\n}\n\nfunction asErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n\ninterface NodeEventListeners {\n stateChange: (nextState: BrowserNodeState) => void;\n error: (nextError: Error) => void;\n}\n\nexport function useFiberNode(options: UseFiberNodeOptions): UseFiberNodeResult {\n const walletId = options.walletId ?? `wallet-${options.network}`;\n const [state, setState] = useState<BrowserNodeState>('idle');\n const [nodeInfo, setNodeInfo] = useState<NodeInfoResult | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [isPasskeySupported, setIsPasskeySupported] = useState(false);\n const [passkeySupportReason, setPasskeySupportReason] = useState<PasskeySupportReason | null>(\n null,\n );\n const [passkeyUnavailableReason, setPasskeyUnavailableReason] = useState<string | null>(null);\n const [hasPasskeyConfigured, setHasPasskeyConfigured] = useState(false);\n\n const nodeRef = useRef<FiberBrowserNode | null>(null);\n const isMountedRef = useRef(true);\n const nodeListenersRef = useRef<NodeEventListeners | null>(null);\n\n const detachNodeListeners = useCallback((node: FiberBrowserNode | null) => {\n if (!node || !nodeListenersRef.current) {\n return;\n }\n\n node.off('stateChange', nodeListenersRef.current.stateChange);\n node.off('error', nodeListenersRef.current.error);\n nodeListenersRef.current = null;\n }, []);\n\n useEffect(\n () => () => {\n isMountedRef.current = false;\n\n const node = nodeRef.current;\n nodeRef.current = null;\n\n if (node) {\n detachNodeListeners(node);\n void node.stop().catch(() => {});\n }\n },\n [detachNodeListeners],\n );\n\n useEffect(() => {\n if (options.enabled === false) return;\n let cancelled = false;\n\n PasskeyCredentialProvider.getSupportStatus()\n .then((status) => {\n if (!cancelled) {\n const supported = isPasskeyPotentiallySupported(status);\n setIsPasskeySupported(supported);\n setPasskeySupportReason(status.reason);\n setPasskeyUnavailableReason(supported ? null : toPasskeyUnavailableReason(status.reason));\n }\n })\n .catch((supportError) => {\n if (!cancelled) {\n setIsPasskeySupported(false);\n setPasskeySupportReason('unknown');\n setPasskeyUnavailableReason(toPasskeyUnavailableReason('unknown'));\n }\n\n if (supportError instanceof Error) {\n console.warn('[fiber-pay/react] Failed to detect passkey support:', supportError.message);\n }\n });\n\n const provider = new PasskeyCredentialProvider(walletId);\n setHasPasskeyConfigured(provider.isConfigured());\n\n return () => {\n cancelled = true;\n };\n }, [walletId, options.enabled]);\n\n const initNode = useCallback(\n (\n credential: PasswordCredentialProvider | PasskeyCredentialProvider | RawKeyCredentialProvider,\n ) => {\n if (nodeRef.current) {\n const existingState = nodeRef.current.state;\n if (existingState !== 'idle' && existingState !== 'stopped' && existingState !== 'error') {\n throw new Error('Node already running');\n }\n\n detachNodeListeners(nodeRef.current);\n nodeRef.current = null;\n }\n\n const nodeConfig: ConstructorParameters<typeof FiberBrowserNode>[0] = {\n network: options.network,\n credential,\n nodeConfig: {\n databasePrefix: `/${walletId}`,\n ...(options.nodeConfig ?? {}),\n },\n };\n\n if (options.wasmFactory) {\n nodeConfig.wasmFactory = options.wasmFactory;\n }\n\n const node = new FiberBrowserNode(nodeConfig);\n\n nodeRef.current = node;\n\n const listeners: NodeEventListeners = {\n stateChange: (nextState) => {\n if (!isMountedRef.current) {\n return;\n }\n\n setState(nextState);\n if (nextState === 'stopped') {\n setNodeInfo(null);\n }\n },\n error: (nextError: Error) => {\n if (!isMountedRef.current) {\n return;\n }\n\n setError(nextError.message);\n },\n };\n\n nodeListenersRef.current = listeners;\n node.on('stateChange', listeners.stateChange);\n node.on('error', listeners.error);\n\n return node;\n },\n [detachNodeListeners, options.network, options.nodeConfig, options.wasmFactory, walletId],\n );\n\n const cleanupFailedStart = useCallback(\n async (node: FiberBrowserNode | null) => {\n if (!node) {\n return;\n }\n\n try {\n if (node.state !== 'idle' && node.state !== 'stopped') {\n await node.stop();\n }\n } catch {\n // Ignore cleanup failures after a start error.\n } finally {\n detachNodeListeners(node);\n if (nodeRef.current === node) {\n nodeRef.current = null;\n }\n }\n },\n [detachNodeListeners],\n );\n\n const startWithPassword = useCallback(\n async (password: string) => {\n setError(null);\n let node: FiberBrowserNode | null = null;\n\n try {\n const credential = new PasswordCredentialProvider(walletId);\n node = initNode(credential);\n const info = await node.start({ unlockParams: { password } });\n if (isMountedRef.current) {\n setNodeInfo(info);\n }\n } catch (startError) {\n if (isMountedRef.current) {\n setError(asErrorMessage(startError));\n }\n\n await cleanupFailedStart(node);\n }\n },\n [cleanupFailedStart, initNode, walletId],\n );\n\n const createPasskeyAndStart = useCallback(\n async (username = 'User') => {\n setError(null);\n let node: FiberBrowserNode | null = null;\n\n try {\n const credential = new PasskeyCredentialProvider(walletId);\n await credential.register(username);\n if (isMountedRef.current) {\n setHasPasskeyConfigured(true);\n }\n\n node = initNode(credential);\n const info = await node.start();\n if (isMountedRef.current) {\n setNodeInfo(info);\n }\n } catch (startError) {\n if (isMountedRef.current) {\n setError(asErrorMessage(startError));\n }\n\n await cleanupFailedStart(node);\n }\n },\n [cleanupFailedStart, initNode, walletId],\n );\n\n const startWithPasskey = useCallback(async () => {\n setError(null);\n let node: FiberBrowserNode | null = null;\n\n try {\n const credential = new PasskeyCredentialProvider(walletId);\n node = initNode(credential);\n const info = await node.start();\n if (isMountedRef.current) {\n setNodeInfo(info);\n }\n } catch (startError) {\n if (isMountedRef.current) {\n setError(asErrorMessage(startError));\n }\n\n await cleanupFailedStart(node);\n }\n }, [cleanupFailedStart, initNode, walletId]);\n\n const startWithRawKey = useCallback(\n async (fiberKey: Uint8Array, ckbSecretKey?: Uint8Array) => {\n setError(null);\n let node: FiberBrowserNode | null = null;\n\n try {\n const credential = new RawKeyCredentialProvider(fiberKey, ckbSecretKey, walletId);\n node = initNode(credential);\n const info = await node.start();\n if (isMountedRef.current) {\n setNodeInfo(info);\n }\n } catch (startError) {\n if (isMountedRef.current) {\n setError(asErrorMessage(startError));\n }\n\n await cleanupFailedStart(node);\n }\n },\n [cleanupFailedStart, initNode, walletId],\n );\n\n const stop = useCallback(async () => {\n const node = nodeRef.current;\n if (!node) {\n return;\n }\n\n try {\n await node.stop();\n } catch (stopError) {\n if (isMountedRef.current) {\n setError(asErrorMessage(stopError));\n }\n } finally {\n detachNodeListeners(node);\n if (nodeRef.current === node) {\n nodeRef.current = null;\n }\n\n if (isMountedRef.current) {\n setNodeInfo(null);\n }\n }\n }, [detachNodeListeners]);\n\n const isStarting = useMemo(() => state === 'unlocking' || state === 'starting', [state]);\n const isRunning = useMemo(() => state === 'running', [state]);\n\n return {\n state,\n node: nodeRef.current,\n nodeInfo,\n error,\n isStarting,\n isRunning,\n isPasskeySupported,\n passkeySupportReason,\n passkeyUnavailableReason,\n hasPasskeyConfigured,\n startWithPassword,\n createPasskeyAndStart,\n startWithPasskey,\n startWithRawKey,\n stop,\n };\n}\n","import type { GetPaymentResult } from '@fiber-pay/sdk/browser';\nimport { type CSSProperties, useEffect, useId, useState } from 'react';\nimport { useFiberNode } from './use-fiber-node.js';\nimport { useFiberPayment } from './use-fiber-payment.js';\n\nexport interface FiberPayQuickCardProps {\n network?: 'testnet' | 'mainnet';\n walletId?: string;\n passkeyUsername?: string;\n title?: string;\n className?: string;\n style?: CSSProperties;\n onInvoiceCreated?: (invoice: string) => void;\n onPaymentResult?: (result: GetPaymentResult) => void;\n onError?: (error: { scope: 'node' | 'payment' | 'invoice'; message: string }) => void;\n}\n\nconst ONE_CKB_SHANNONS = '0x5f5e100';\n\nconst cardStyle: CSSProperties = {\n border: '1px solid #ddd',\n borderRadius: 8,\n padding: 16,\n maxWidth: 520,\n};\n\nconst rowStyle: CSSProperties = {\n display: 'flex',\n gap: 8,\n};\n\nconst rowWithMarginStyle: CSSProperties = {\n ...rowStyle,\n marginBottom: 8,\n};\n\nexport function FiberPayQuickCard(props: FiberPayQuickCardProps) {\n const network = props.network ?? 'testnet';\n const passkeyUsername = props.passkeyUsername ?? 'User';\n const title = props.title ?? 'FiberPay Quick Card';\n const onError = props.onError;\n const onInvoiceCreated = props.onInvoiceCreated;\n const onPaymentResult = props.onPaymentResult;\n const passwordInputId = useId();\n const invoiceInputId = useId();\n\n const {\n node,\n nodeInfo,\n state,\n error: nodeError,\n isPasskeySupported,\n hasPasskeyConfigured,\n startWithPassword,\n startWithPasskey,\n createPasskeyAndStart,\n stop,\n } = useFiberNode({ network, walletId: props.walletId });\n\n const { payInvoice, isPaying, error: payError, paymentResult } = useFiberPayment(node);\n\n const [password, setPassword] = useState('');\n const [invoiceInput, setInvoiceInput] = useState('');\n const [createdInvoice, setCreatedInvoice] = useState('');\n const [isCreatingInvoice, setIsCreatingInvoice] = useState(false);\n const [invoiceError, setInvoiceError] = useState<string | null>(null);\n\n useEffect(() => {\n if (nodeError) {\n onError?.({ scope: 'node', message: nodeError });\n }\n }, [nodeError, onError]);\n\n useEffect(() => {\n if (payError) {\n onError?.({ scope: 'payment', message: payError });\n }\n }, [onError, payError]);\n\n useEffect(() => {\n if (paymentResult) {\n onPaymentResult?.(paymentResult);\n }\n }, [onPaymentResult, paymentResult]);\n\n const createInvoice = async () => {\n if (!node) {\n return;\n }\n\n setIsCreatingInvoice(true);\n setInvoiceError(null);\n try {\n const created = await node.newInvoice({\n amount: ONE_CKB_SHANNONS,\n currency: network === 'mainnet' ? 'Fibb' : 'Fibt',\n description: 'FiberPay QuickCard invoice',\n });\n setCreatedInvoice(created.invoice_address);\n onInvoiceCreated?.(created.invoice_address);\n } catch (createInvoiceError) {\n const message =\n createInvoiceError instanceof Error\n ? createInvoiceError.message\n : String(createInvoiceError);\n setInvoiceError(message);\n onError?.({ scope: 'invoice', message });\n } finally {\n setIsCreatingInvoice(false);\n }\n };\n\n return (\n <div style={{ ...cardStyle, ...props.style }} className={props.className}>\n <h3>\n {title} ({network})\n </h3>\n\n {!nodeInfo ? (\n <>\n {isPasskeySupported ? (\n <div style={rowWithMarginStyle}>\n {hasPasskeyConfigured ? (\n <button type=\"button\" onClick={() => void startWithPasskey()}>\n Login with Passkey\n </button>\n ) : (\n <button type=\"button\" onClick={() => void createPasskeyAndStart(passkeyUsername)}>\n Register Passkey\n </button>\n )}\n </div>\n ) : null}\n\n <label htmlFor={passwordInputId}>Password</label>\n <div style={rowStyle}>\n <input\n id={passwordInputId}\n type=\"password\"\n autoComplete=\"current-password\"\n aria-label=\"Node password\"\n value={password}\n onChange={(event) => setPassword(event.target.value)}\n placeholder=\"Password\"\n />\n <button type=\"button\" onClick={() => void startWithPassword(password)}>\n Start with Password\n </button>\n </div>\n </>\n ) : (\n <>\n <p>\n <strong>State:</strong> {state}\n </p>\n <p>\n <strong>Pubkey:</strong> {nodeInfo.pubkey}\n </p>\n\n <div style={rowWithMarginStyle}>\n <button type=\"button\" onClick={() => void createInvoice()} disabled={isCreatingInvoice}>\n {isCreatingInvoice ? 'Creating...' : 'Create Invoice (1 CKB)'}\n </button>\n <button type=\"button\" onClick={() => void stop()}>\n Stop Node\n </button>\n </div>\n\n {createdInvoice ? (\n <p>\n <strong>Created invoice:</strong> {createdInvoice}\n </p>\n ) : null}\n\n <label htmlFor={invoiceInputId}>Invoice</label>\n <div style={rowStyle}>\n <input\n id={invoiceInputId}\n aria-label=\"Invoice to pay\"\n value={invoiceInput}\n onChange={(event) => setInvoiceInput(event.target.value)}\n placeholder=\"Paste invoice to pay\"\n />\n <button type=\"button\" onClick={() => void payInvoice(invoiceInput)} disabled={isPaying}>\n {isPaying ? 'Paying...' : 'Pay'}\n </button>\n </div>\n\n {paymentResult ? (\n <p>\n <strong>Payment:</strong> {paymentResult.status}\n </p>\n ) : null}\n </>\n )}\n\n {nodeError ? (\n <p style={{ color: '#b91c1c' }}>\n <strong>Node error:</strong> {nodeError}\n </p>\n ) : null}\n {payError ? (\n <p style={{ color: '#b91c1c' }}>\n <strong>Payment error:</strong> {payError}\n </p>\n ) : null}\n {invoiceError ? (\n <p style={{ color: '#b91c1c' }}>\n <strong>Invoice error:</strong> {invoiceError}\n </p>\n ) : null}\n </div>\n );\n}\n","import type { FiberBrowserNode, GetPaymentResult } from '@fiber-pay/sdk/browser';\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nexport interface UseFiberPaymentResult {\n payInvoice: (invoice: string) => Promise<void>;\n isPaying: boolean;\n paymentResult: GetPaymentResult | null;\n error: string | null;\n}\n\nfunction asErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n\nexport function useFiberPayment(node: FiberBrowserNode | null): UseFiberPaymentResult {\n const [isPaying, setIsPaying] = useState(false);\n const [paymentResult, setPaymentResult] = useState<GetPaymentResult | null>(null);\n const [error, setError] = useState<string | null>(null);\n const isMountedRef = useRef(true);\n\n useEffect(\n () => () => {\n isMountedRef.current = false;\n },\n [],\n );\n\n const payInvoice = useCallback(\n async (invoice: string) => {\n if (!node) {\n if (isMountedRef.current) {\n setError('Node is not initialized');\n }\n return;\n }\n\n if (isMountedRef.current) {\n setIsPaying(true);\n setError(null);\n setPaymentResult(null);\n }\n\n try {\n const parsed = await node.parseInvoice({ invoice });\n await node.sendPayment({ invoice });\n\n const paymentHash = parsed.invoice.data.payment_hash;\n const result = await node.waitForPayment(paymentHash);\n\n if (result.status === 'Failed') {\n throw new Error(result.failed_error ?? 'Payment failed during routing/execution');\n }\n\n if (isMountedRef.current) {\n setPaymentResult(result);\n }\n } catch (payError) {\n if (isMountedRef.current) {\n setError(asErrorMessage(payError));\n }\n } finally {\n if (isMountedRef.current) {\n setIsPaying(false);\n }\n }\n },\n [node],\n );\n\n return {\n payInvoice,\n isPaying,\n paymentResult,\n error,\n };\n}\n","/**\n * NodeInfoPanel — Displays Fiber browser node metadata, stats, and optional QR code.\n *\n * This is a stateless display component that polls the running node for stats\n * (peer count, channel count, CKB balance) and renders them with copy-to-clipboard\n * support and an optional QR code for the node's CKB address.\n *\n * @example\n * ```tsx\n * import { NodeInfoPanel } from \"@fiber-pay/react\";\n *\n * <NodeInfoPanel node={node} network=\"testnet\" showQrCode />\n * ```\n */\n\nimport type { FiberBrowserNode } from '@fiber-pay/sdk/browser';\nimport {\n ConfigBuilder,\n formatShannonsAsCkb,\n getLockBalanceShannons,\n scriptToAddress,\n} from '@fiber-pay/sdk/browser';\nimport {\n type ComponentType,\n type CSSProperties,\n type ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface NodeInfoPanelProps {\n /** The running FiberBrowserNode instance. */\n node: FiberBrowserNode | null;\n\n /** Network (needed for address derivation and RPC URL defaults). */\n network: 'testnet' | 'mainnet';\n\n /** How often to refresh stats (ms). Default: 15000. */\n pollInterval?: number;\n\n /** Whether to show a QR code of the CKB address. Requires `qrcode.react` to be installed. */\n showQrCode?: boolean;\n\n /**\n * Optional QR code render function — allows consumers to bring their own QR library.\n * Called with the CKB address string. If not provided and `showQrCode` is true,\n * the component will attempt to dynamically import `qrcode.react`.\n */\n renderQrCode?: (value: string) => ReactNode;\n\n /** Additional CSS class name(s). */\n className?: string;\n\n /** Inline styles. */\n style?: CSSProperties;\n}\n\ninterface NodeStats {\n pubkey: string;\n peers: number;\n channels: number;\n ckbAddress: string | null;\n balanceCkb: string | null;\n externalFunding: boolean;\n}\n\n// =============================================================================\n// Helpers\n// =============================================================================\n\nfunction truncateMiddle(str: string, left = 8, right = 8): string {\n if (str.length <= left + right + 3) return str;\n return `${str.slice(0, left)}…${str.slice(-right)}`;\n}\n\nfunction copyToClipboard(text: string) {\n void navigator.clipboard.writeText(text);\n}\n\nasync function fetchNodeStats(\n node: FiberBrowserNode,\n network: 'testnet' | 'mainnet',\n): Promise<NodeStats> {\n const [nodeInfo, peers, channels] = await Promise.all([\n node.nodeInfo(),\n node.listPeers(),\n node.listChannels(),\n ]);\n\n const lockScript = nodeInfo.default_funding_lock_script;\n const ckbRpcUrl = ConfigBuilder.getDefaults(network).ckbRpcUrl;\n\n if (!lockScript || lockScript.args === '0x') {\n return {\n pubkey: nodeInfo.pubkey,\n peers: peers.peers.length,\n channels: channels.channels.length,\n ckbAddress: null,\n balanceCkb: null,\n externalFunding: true,\n };\n }\n\n const ckbAddress = scriptToAddress(lockScript, network);\n const balanceShannons = await getLockBalanceShannons(ckbRpcUrl, lockScript);\n const balanceCkb = formatShannonsAsCkb(balanceShannons, 4);\n\n return {\n pubkey: nodeInfo.pubkey,\n peers: peers.peers.length,\n channels: channels.channels.length,\n ckbAddress,\n balanceCkb,\n externalFunding: false,\n };\n}\n\n// =============================================================================\n// CSS\n// =============================================================================\n\nconst styles = {\n root: {\n fontFamily: 'system-ui, -apple-system, sans-serif',\n fontSize: '0.875rem',\n color: 'var(--fpay-text-primary, #111827)',\n } satisfies CSSProperties,\n\n idle: {\n padding: '1rem',\n textAlign: 'center',\n color: 'var(--fpay-text-secondary, #6b7280)',\n fontSize: '0.75rem',\n } satisfies CSSProperties,\n\n loading: {\n display: 'flex',\n alignItems: 'center',\n gap: '0.5rem',\n padding: '0.5rem 0',\n fontSize: '0.75rem',\n color: 'var(--fpay-text-secondary, #6b7280)',\n } satisfies CSSProperties,\n\n errorBox: {\n marginBottom: '0.5rem',\n padding: '0.375rem 0.5rem',\n fontSize: '0.75rem',\n borderRadius: '0.5rem',\n border: '1px solid var(--fpay-error-border, rgba(239,68,68,0.3))',\n backgroundColor: 'var(--fpay-error-bg, rgba(239,68,68,0.1))',\n color: 'var(--fpay-error, #ef4444)',\n } satisfies CSSProperties,\n\n infoRow: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n gap: '0.75rem',\n padding: '0.375rem 0',\n } satisfies CSSProperties,\n\n infoLabel: {\n fontSize: '0.75rem',\n color: 'var(--fpay-text-secondary, #6b7280)',\n } satisfies CSSProperties,\n\n infoValueWrapper: {\n display: 'flex',\n alignItems: 'center',\n gap: '0.375rem',\n } satisfies CSSProperties,\n\n infoValue: {\n fontFamily: 'ui-monospace, monospace',\n fontSize: '0.75rem',\n color: 'var(--fpay-text-primary, #111827)',\n } satisfies CSSProperties,\n\n copyButton: {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '0.25rem',\n borderRadius: '0.25rem',\n border: 'none',\n background: 'none',\n cursor: 'pointer',\n color: 'var(--fpay-text-secondary, #6b7280)',\n transition: 'color 0.15s',\n } satisfies CSSProperties,\n\n statsGrid: {\n display: 'grid',\n gridTemplateColumns: '1fr 1fr',\n gap: '0.5rem',\n marginTop: '0.5rem',\n } satisfies CSSProperties,\n\n statCard: {\n padding: '0.375rem 0.5rem',\n textAlign: 'center',\n borderRadius: '0.5rem',\n border: '1px solid var(--fpay-border, #e5e7eb)',\n backgroundColor: 'var(--fpay-bg-secondary, #f9fafb)',\n } satisfies CSSProperties,\n\n statLabel: {\n fontSize: '0.625rem',\n color: 'var(--fpay-text-secondary, #6b7280)',\n } satisfies CSSProperties,\n\n statValue: {\n fontSize: '0.875rem',\n fontWeight: 600,\n color: 'var(--fpay-text-primary, #111827)',\n } satisfies CSSProperties,\n\n qrContainer: {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: '0.25rem',\n marginTop: '0.75rem',\n padding: '0.5rem',\n borderRadius: '0.5rem',\n border: '1px solid var(--fpay-border, #e5e7eb)',\n backgroundColor: 'var(--fpay-bg-secondary, #f9fafb)',\n } satisfies CSSProperties,\n\n qrCaption: {\n fontSize: '0.625rem',\n color: 'var(--fpay-text-secondary, #6b7280)',\n } satisfies CSSProperties,\n\n balanceRow: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n width: '100%',\n marginTop: '0.5rem',\n paddingTop: '0.5rem',\n borderTop: '1px solid var(--fpay-border, #e5e7eb)',\n } satisfies CSSProperties,\n\n statusBadge: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '0.375rem',\n padding: '0.25rem 0.625rem',\n fontSize: '0.75rem',\n fontWeight: 500,\n borderRadius: '9999px',\n marginBottom: '0.5rem',\n } satisfies CSSProperties,\n};\n\nconst STATUS_COLORS: Record<string, { bg: string; fg: string; dot: string }> = {\n idle: { bg: 'rgba(107,114,128,0.1)', fg: '#6b7280', dot: '#9ca3af' },\n unlocking: { bg: 'rgba(245,158,11,0.1)', fg: '#d97706', dot: '#f59e0b' },\n starting: { bg: 'rgba(245,158,11,0.1)', fg: '#d97706', dot: '#f59e0b' },\n running: { bg: 'rgba(34,197,94,0.1)', fg: '#16a34a', dot: '#22c55e' },\n stopping: { bg: 'rgba(245,158,11,0.1)', fg: '#d97706', dot: '#f59e0b' },\n stopped: { bg: 'rgba(107,114,128,0.1)', fg: '#6b7280', dot: '#9ca3af' },\n error: { bg: 'rgba(239,68,68,0.1)', fg: '#dc2626', dot: '#ef4444' },\n};\n\n// =============================================================================\n// Sub-components\n// =============================================================================\n\nfunction CopyIcon() {\n return (\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" />\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\n </svg>\n );\n}\n\nfunction InfoRow({ label, value, copyable }: { label: string; value: string; copyable?: boolean }) {\n return (\n <div style={styles.infoRow}>\n <span style={styles.infoLabel}>{label}</span>\n <div style={styles.infoValueWrapper}>\n <span style={styles.infoValue}>{truncateMiddle(value, 6, 6)}</span>\n {copyable && (\n <button\n type=\"button\"\n onClick={() => copyToClipboard(value)}\n style={styles.copyButton}\n title=\"Copy to clipboard\"\n aria-label={`Copy ${label}`}\n >\n <CopyIcon />\n </button>\n )}\n </div>\n </div>\n );\n}\n\n// =============================================================================\n// Component\n// =============================================================================\n\nexport function NodeInfoPanel(props: NodeInfoPanelProps) {\n const {\n node,\n network,\n pollInterval = 15000,\n showQrCode = false,\n renderQrCode,\n className,\n style,\n } = props;\n\n const [stats, setStats] = useState<NodeStats | null>(null);\n const [statsError, setStatsError] = useState<string | null>(null);\n const [statsLoading, setStatsLoading] = useState(false);\n const cancelledRef = useRef(false);\n\n // QR code dynamic import state\n const [QRComponent, setQRComponent] = useState<ComponentType<{\n value: string;\n size?: number;\n bgColor?: string;\n fgColor?: string;\n }> | null>(null);\n\n // Attempt to dynamically import qrcode.react if needed\n useEffect(() => {\n let cancelled = false;\n if (!showQrCode || renderQrCode) return;\n import('qrcode.react')\n .then((mod: Record<string, unknown>) => {\n if (cancelled) return;\n const Comp = (mod.QRCodeSVG ?? mod.default) as\n | ComponentType<{\n value: string;\n size?: number;\n bgColor?: string;\n fgColor?: string;\n }>\n | undefined;\n if (Comp) setQRComponent(() => Comp);\n })\n .catch(() => {\n // qrcode.react not installed — silently skip\n });\n return () => {\n cancelled = true;\n };\n }, [showQrCode, renderQrCode]);\n\n const loadingRef = useRef(false);\n\n const loadStats = useCallback(async () => {\n if (!node || node.state !== 'running' || loadingRef.current) return;\n loadingRef.current = true;\n setStatsLoading(true);\n setStatsError(null);\n try {\n const data = await fetchNodeStats(node, network);\n if (!cancelledRef.current) setStats(data);\n } catch (e) {\n if (!cancelledRef.current) {\n setStatsError(e instanceof Error ? e.message : String(e));\n }\n } finally {\n loadingRef.current = false;\n if (!cancelledRef.current) setStatsLoading(false);\n }\n }, [node, network]);\n\n useEffect(() => {\n cancelledRef.current = false;\n\n if (!node || node.state !== 'running') {\n setStats(null);\n setStatsError(null);\n return;\n }\n\n void loadStats();\n const interval = setInterval(() => void loadStats(), pollInterval);\n return () => {\n cancelledRef.current = true;\n clearInterval(interval);\n };\n }, [node, node?.state, pollInterval, loadStats]);\n\n // --- Render ---------------------------------------------------------------\n\n if (!node) {\n return (\n <div className={className} style={{ ...styles.root, ...style }} data-fpay-node-info=\"\">\n <div style={styles.idle}>No node connected</div>\n </div>\n );\n }\n\n const nodeState = node.state;\n const statusColor = STATUS_COLORS[nodeState] ?? STATUS_COLORS.idle;\n\n return (\n <div className={className} style={{ ...styles.root, ...style }} data-fpay-node-info=\"\">\n {/* Status badge */}\n <div\n style={{\n ...styles.statusBadge,\n backgroundColor: statusColor.bg,\n color: statusColor.fg,\n }}\n >\n <span\n style={{\n display: 'inline-block',\n width: '0.5rem',\n height: '0.5rem',\n borderRadius: '50%',\n backgroundColor: statusColor.dot,\n }}\n />\n {nodeState}\n </div>\n\n {/* Loading indicator */}\n {statsLoading && !stats && (\n <div style={styles.loading}>\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n role=\"img\"\n aria-label=\"Loading\"\n >\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n <animateTransform\n attributeName=\"transform\"\n type=\"rotate\"\n from=\"0 12 12\"\n to=\"360 12 12\"\n dur=\"1s\"\n repeatCount=\"indefinite\"\n />\n </svg>\n Loading…\n </div>\n )}\n\n {/* Error */}\n {statsError && <div style={styles.errorBox}>{statsError}</div>}\n\n {/* Stats */}\n {stats && (\n <>\n <InfoRow label=\"Pubkey\" value={stats.pubkey} copyable />\n\n {stats.externalFunding ? (\n <div style={{ padding: '0.25rem 0', fontSize: '0.75rem', color: '#6b7280' }}>\n External funding mode\n </div>\n ) : stats.ckbAddress ? (\n <InfoRow label=\"CKB Address\" value={stats.ckbAddress} copyable />\n ) : null}\n\n <div style={styles.statsGrid}>\n <div style={styles.statCard}>\n <div style={styles.statLabel}>Peers</div>\n <div style={styles.statValue}>{stats.peers}</div>\n </div>\n <div style={styles.statCard}>\n <div style={styles.statLabel}>Channels</div>\n <div style={styles.statValue}>{stats.channels}</div>\n </div>\n </div>\n\n {/* QR Code */}\n {showQrCode && stats.ckbAddress && (\n <div style={styles.qrContainer}>\n {renderQrCode ? (\n renderQrCode(stats.ckbAddress)\n ) : QRComponent ? (\n <QRComponent\n value={stats.ckbAddress}\n size={120}\n bgColor=\"transparent\"\n fgColor=\"currentColor\"\n />\n ) : (\n <div style={{ fontSize: '0.625rem', color: '#9ca3af' }}>\n Install qrcode.react for QR code\n </div>\n )}\n <span style={styles.qrCaption}>Scan to deposit CKB</span>\n <div style={styles.balanceRow}>\n <span style={{ fontSize: '0.75rem', color: '#6b7280' }}>Balance</span>\n <span\n style={{\n fontFamily: 'ui-monospace, monospace',\n fontSize: '0.75rem',\n fontWeight: 500,\n }}\n >\n {stats.balanceCkb ?? '—'} CKB\n </span>\n </div>\n </div>\n )}\n </>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":["ConfigBuilder","FiberBrowserNode","formatShannonsAsCkb","getLockBalanceShannons","PasskeyCredentialProvider","PasswordCredentialProvider","RawKeyCredentialProvider","scriptToAddress","useCallback","useEffect","useRef","useState","useState","useRef","useEffect","useCallback","useEffect","useState","useCallback","useEffect","useRef","useState","asErrorMessage","Fragment","jsx","jsxs","useState","useEffect","useCallback","useEffect","useRef","useState","Fragment","jsx","jsxs","styles"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/connect-button.tsx","../src/use-fiber-node.ts","../src/fiber-node-button/index.tsx","../src/fiber-node-button/panel.tsx","../src/fiber-node-button/styles.ts","../src/fiber-node-button/utils.ts","../src/fiber-node-button/render-action.tsx","../src/fiber-node-button/types.ts","../src/fiber-node-button/channels-tab.tsx","../src/fiber-node-button/diagnostics-tab.tsx","../src/fiber-node-button/i18n.ts","../src/fiber-node-button/use-panel-state.ts","../src/use-channel-open-flow.ts","../src/use-fiber-payment.ts","../src/fiber-node-button/workbench-tab.tsx","../src/fiber-pay-quick-card.tsx","../src/node-info-panel.tsx"],"sourcesContent":["export type {\n BrowserNodeState,\n FiberBrowserNodeConfig,\n FiberWasmFactory,\n NodeInfoResult,\n PasskeySupportReason,\n} from '@fiber-pay/sdk/browser';\nexport {\n ChannelState,\n ConfigBuilder,\n ckbHash,\n ckbToShannons,\n derivePublicKey,\n FiberBrowserNode,\n FiberRpcError,\n formatShannonsAsCkb,\n fromHex,\n getLockBalanceShannons,\n PasskeyCredentialProvider,\n PasswordCredentialProvider,\n RawKeyCredentialProvider,\n scriptToAddress,\n shannonsToCkb,\n toHex,\n} from '@fiber-pay/sdk/browser';\nexport type {\n ConnectButtonConnectedDropdownContext,\n ConnectButtonProps,\n ConnectStrategy,\n} from './connect-button.js';\nexport { ConnectButton } from './connect-button.js';\nexport type {\n FiberNodeButtonActionDefaultProps,\n FiberNodeButtonActionId,\n FiberNodeButtonConnectorSectionContext,\n FiberNodeButtonExternalFundingConfig,\n FiberNodeButtonExternalFundingResolved,\n FiberNodeButtonExternalFundingResolverContext,\n FiberNodeButtonI18n,\n FiberNodeButtonProps,\n FiberNodeButtonRenderAction,\n FiberNodeButtonRenderActionContext,\n FiberNodeButtonTabActions,\n FiberNodeButtonTabConfig,\n FiberNodeButtonTabContext,\n FiberNodeButtonTabId,\n} from './fiber-node-button.js';\nexport { FiberNodeButton } from './fiber-node-button.js';\nexport type { FiberPayQuickCardProps } from './fiber-pay-quick-card.js';\nexport { FiberPayQuickCard } from './fiber-pay-quick-card.js';\nexport type { NodeInfoPanelProps } from './node-info-panel.js';\nexport { NodeInfoPanel } from './node-info-panel.js';\nexport type {\n ChannelOpenFlowParams,\n ChannelOpenFlowResult,\n UseChannelOpenFlowOptions,\n UseChannelOpenFlowResult,\n} from './use-channel-open-flow.js';\nexport { useChannelOpenFlow } from './use-channel-open-flow.js';\nexport type { UseFiberNodeOptions, UseFiberNodeResult } from './use-fiber-node.js';\nexport { useFiberNode } from './use-fiber-node.js';\nexport type { UseFiberPaymentResult } from './use-fiber-payment.js';\nexport { useFiberPayment } from './use-fiber-payment.js';\n","/**\n * ConnectButton — A unified connect/disconnect button for Fiber browser nodes.\n *\n * Supports three usage modes:\n * 1. **Standalone** — Internally manages `useFiberNode`. Simplest API.\n * 2. **External hook** — Accepts a pre-existing `useFiberNode` result via the `fiber` prop,\n * so sibling components can share the same node instance.\n * 3. **Auto-detection** — If `fiber` is provided, uses it; otherwise creates its own.\n *\n * @example Standalone\n * ```tsx\n * <ConnectButton network=\"testnet\" strategy=\"passkey\" onConnect={(node) => setNode(node)} />\n * ```\n *\n * @example External hook\n * ```tsx\n * const fiber = useFiberNode({ network: \"testnet\" });\n * <ConnectButton fiber={fiber} strategy=\"passkey\" />\n * ```\n */\n\nimport type { FiberBrowserNode, FiberWasmFactory, NodeInfoResult } from '@fiber-pay/sdk/browser';\nimport {\n type CSSProperties,\n type ReactNode,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n} from 'react';\nimport type { UseFiberNodeOptions, UseFiberNodeResult } from './use-fiber-node.js';\nimport { useFiberNode } from './use-fiber-node.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/** Credential strategy the ConnectButton should use */\nexport type ConnectStrategy = 'passkey' | 'password';\n\nexport interface ConnectButtonProps {\n /** Network to connect to. Required in standalone mode; ignored when `fiber` is provided. */\n network?: 'testnet' | 'mainnet';\n\n /**\n * Pre-existing hook result from `useFiberNode()`.\n * When provided, the button delegates to this instead of creating its own hook.\n */\n fiber?: UseFiberNodeResult;\n\n /** Credential strategy. Defaults to `\"passkey\"`. */\n strategy?: ConnectStrategy;\n\n /**\n * Enable external wallet mode (no internal CKB key derivation).\n * Only applies when ConnectButton manages its own `useFiberNode` instance.\n */\n externalWallet?: boolean;\n\n /** Password for the \"password\" strategy. */\n password?: string;\n\n /** Wallet identifier for IndexedDB isolation. */\n walletId?: string;\n\n /** Display name for passkey registration. */\n passkeyUsername?: string;\n\n /** Optional WASM factory override. */\n wasmFactory?: FiberWasmFactory;\n\n /** Additional node config. */\n nodeConfig?: UseFiberNodeOptions['nodeConfig'];\n\n /** Additional CSS class name(s) for the root container. */\n className?: string;\n\n /** Inline styles for the root container. */\n style?: CSSProperties;\n\n /** Inline styles for the connected dropdown container. */\n dropdownStyle?: CSSProperties;\n\n /**\n * Optional custom renderer for the connected dropdown content.\n * Use this to render project-specific controls (for example peer/channel actions)\n * while reusing the SDK's connect/disconnect lifecycle logic via the provided context.\n * When set, this replaces the default dropdown content, so custom renderers must\n * render their own disconnect UI if they want to expose disconnect actions.\n */\n renderConnectedDropdown?: (context: ConnectButtonConnectedDropdownContext) => ReactNode;\n\n /**\n * Called when the node reaches the \"running\" state.\n * Receives the `FiberBrowserNode` instance and its `NodeInfoResult`.\n */\n onConnect?: (node: FiberBrowserNode, nodeInfo: NodeInfoResult) => void;\n\n /** Called after the node is stopped. */\n onDisconnect?: () => void;\n\n /** Called when an error occurs. */\n onError?: (error: string) => void;\n}\n\nexport interface ConnectButtonConnectedDropdownContext {\n fiber: UseFiberNodeResult;\n closeDropdown: () => void;\n disconnect: () => Promise<void>;\n}\n\n// =============================================================================\n// Helpers\n// =============================================================================\n\nfunction truncateNodeId(id: string): string {\n if (id.length <= 16) return id;\n return `${id.slice(0, 8)}…${id.slice(-4)}`;\n}\n\n// =============================================================================\n// CSS (inline defaults using CSS custom properties)\n// =============================================================================\n\nconst styles = {\n root: {\n position: 'relative',\n display: 'inline-flex',\n alignItems: 'center',\n gap: '0.5rem',\n fontFamily: 'system-ui, -apple-system, sans-serif',\n } satisfies CSSProperties,\n\n button: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '0.5rem',\n padding: '0.5rem 1.25rem',\n fontSize: '0.875rem',\n fontWeight: 600,\n borderRadius: '9999px',\n border: 'none',\n cursor: 'pointer',\n transition: 'background-color 0.15s, opacity 0.15s',\n lineHeight: 1.4,\n } satisfies CSSProperties,\n\n connectButton: {\n backgroundColor: 'var(--fpay-accent, #6366f1)',\n color: 'var(--fpay-accent-fg, #fff)',\n } satisfies CSSProperties,\n\n connectedButton: {\n backgroundColor: 'var(--fpay-accent-subtle, rgba(99,102,241,0.12))',\n color: 'var(--fpay-accent, #6366f1)',\n border: '1px solid var(--fpay-accent-border, rgba(99,102,241,0.35))',\n } satisfies CSSProperties,\n\n disabledButton: {\n opacity: 0.6,\n cursor: 'not-allowed',\n } satisfies CSSProperties,\n\n statusDot: {\n display: 'inline-block',\n width: '0.5rem',\n height: '0.5rem',\n borderRadius: '50%',\n backgroundColor: 'var(--fpay-accent, #6366f1)',\n } satisfies CSSProperties,\n\n errorText: {\n fontSize: '0.75rem',\n color: 'var(--fpay-error, #ef4444)',\n maxWidth: '220px',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n } satisfies CSSProperties,\n\n dropdown: {\n position: 'absolute',\n right: 0,\n top: '100%',\n marginTop: '0.5rem',\n width: '280px',\n borderRadius: '0.75rem',\n border: '1px solid var(--fpay-border, #e5e7eb)',\n backgroundColor: 'var(--fpay-bg-elevated, #fff)',\n padding: '1rem',\n boxShadow: '0 10px 25px rgba(0,0,0,0.1)',\n zIndex: 100,\n } satisfies CSSProperties,\n\n infoRow: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n padding: '0.375rem 0',\n fontSize: '0.75rem',\n } satisfies CSSProperties,\n\n infoLabel: {\n color: 'var(--fpay-text-secondary, #6b7280)',\n } satisfies CSSProperties,\n\n infoValue: {\n fontFamily: 'ui-monospace, monospace',\n color: 'var(--fpay-text-primary, #111827)',\n } satisfies CSSProperties,\n\n separator: {\n borderTop: '1px solid var(--fpay-border, #e5e7eb)',\n margin: '0.75rem 0',\n } satisfies CSSProperties,\n\n disconnectButton: {\n display: 'flex',\n width: '100%',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '0.625rem 0.75rem',\n fontSize: '0.875rem',\n fontWeight: 600,\n border: '1px solid var(--fpay-border, #e5e7eb)',\n borderRadius: '0.5rem',\n backgroundColor: 'var(--fpay-bg-secondary, #f9fafb)',\n color: 'var(--fpay-text-primary, #111827)',\n cursor: 'pointer',\n transition: 'background-color 0.15s',\n } satisfies CSSProperties,\n\n spinner: {\n animation: 'fpay-spin 1s linear infinite',\n } satisfies CSSProperties,\n};\n\n// Keyframes are injected once via a <style> tag\nconst KEYFRAMES_ID = 'fpay-connect-button-keyframes';\nfunction ensureKeyframes() {\n if (typeof document === 'undefined') return;\n if (document.getElementById(KEYFRAMES_ID)) return;\n const style = document.createElement('style');\n style.id = KEYFRAMES_ID;\n style.textContent = `@keyframes fpay-spin { to { transform: rotate(360deg); } }`;\n document.head.appendChild(style);\n}\n\n// =============================================================================\n// Spinner SVG\n// =============================================================================\n\nfunction Spinner({ size = 16 }: { size?: number }) {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={styles.spinner}\n role=\"img\"\n aria-label=\"Loading\"\n >\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n </svg>\n );\n}\n\n// Chevron SVG for the dropdown toggle\nfunction Chevron({ open }: { open: boolean }) {\n return (\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{ transition: 'transform 0.15s', transform: open ? 'rotate(180deg)' : 'none' }}\n aria-hidden=\"true\"\n >\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n );\n}\n\n// =============================================================================\n// Component\n// =============================================================================\n\nexport function ConnectButton(props: ConnectButtonProps) {\n const {\n network = 'testnet',\n fiber: externalFiber,\n strategy = 'passkey',\n externalWallet = false,\n password,\n walletId,\n passkeyUsername = 'User',\n wasmFactory,\n nodeConfig,\n className,\n style,\n dropdownStyle,\n renderConnectedDropdown,\n onConnect,\n onDisconnect,\n onError,\n } = props;\n\n // --- Hook: internal or external -------------------------------------------\n const internalFiber = useFiberNode({\n network,\n walletId,\n wasmFactory,\n nodeConfig,\n externalWallet,\n enabled: !externalFiber,\n });\n\n const fiber = externalFiber ?? internalFiber;\n\n const {\n state,\n node,\n nodeInfo,\n error,\n isStarting,\n isRunning,\n isPasskeySupported,\n passkeyUnavailableReason,\n hasPasskeyConfigured,\n createPasskeyAndStart,\n startWithPasskey,\n startWithPassword,\n stop,\n } = fiber;\n\n // --- Local UI state -------------------------------------------------------\n const [isConnecting, setIsConnecting] = useState(false);\n const [showDropdown, setShowDropdown] = useState(false);\n const [localError, setLocalError] = useState<string | null>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const dropdownId = useId();\n const lastReportedErrorRef = useRef<string | null>(null);\n\n const effectiveIsStarting = isConnecting || isStarting;\n\n // Inject keyframes on mount\n useEffect(() => ensureKeyframes(), []);\n\n // Click-outside to close dropdown\n useEffect(() => {\n if (!showDropdown) return;\n function handleClickOutside(e: MouseEvent) {\n if (dropdownRef.current && !dropdownRef.current.contains(e.target as Node)) {\n setShowDropdown(false);\n }\n }\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, [showDropdown]);\n\n // Notify parent on connect/disconnect\n const prevRunningRef = useRef(false);\n useEffect(() => {\n if (isRunning && !prevRunningRef.current && node && nodeInfo) {\n onConnect?.(node, nodeInfo);\n }\n if (!isRunning && prevRunningRef.current) {\n onDisconnect?.();\n }\n prevRunningRef.current = isRunning;\n }, [isRunning, node, nodeInfo, onConnect, onDisconnect]);\n\n // Notify parent on error once per distinct message.\n const effectiveError = error ?? localError;\n useEffect(() => {\n if (!effectiveError) {\n lastReportedErrorRef.current = null;\n return;\n }\n\n if (lastReportedErrorRef.current === effectiveError) {\n return;\n }\n\n lastReportedErrorRef.current = effectiveError;\n onError?.(effectiveError);\n }, [effectiveError, onError]);\n\n // --- Actions --------------------------------------------------------------\n\n const handleConnect = useCallback(async () => {\n setIsConnecting(true);\n setLocalError(null);\n try {\n switch (strategy) {\n case 'password':\n if (!password) throw new Error('Password is required for \"password\" strategy');\n await startWithPassword(password);\n break;\n case 'passkey':\n if (hasPasskeyConfigured) {\n await startWithPasskey();\n } else {\n await createPasskeyAndStart(passkeyUsername);\n }\n break;\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n setLocalError(msg);\n } finally {\n setIsConnecting(false);\n }\n }, [\n strategy,\n password,\n passkeyUsername,\n hasPasskeyConfigured,\n startWithPassword,\n startWithPasskey,\n createPasskeyAndStart,\n ]);\n\n const handleDisconnect = useCallback(async () => {\n try {\n await stop();\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n setLocalError(msg);\n } finally {\n setShowDropdown(false);\n }\n }, [stop]);\n\n const closeDropdown = useCallback(() => {\n setShowDropdown(false);\n }, []);\n\n // --- Render ---------------------------------------------------------------\n\n const hasError = !!effectiveError;\n\n // Determine button content and behaviour\n let buttonLabel: ReactNode;\n let buttonOnClick: (() => void) | undefined;\n let buttonDisabled = false;\n let buttonStyle: CSSProperties;\n\n if (isRunning) {\n buttonLabel = (\n <>\n <span style={styles.statusDot} />\n <span style={{ fontFamily: 'ui-monospace, monospace' }}>\n {nodeInfo?.pubkey ? truncateNodeId(nodeInfo.pubkey) : 'Connected'}\n </span>\n <Chevron open={showDropdown} />\n </>\n );\n buttonOnClick = () => setShowDropdown((s) => !s);\n buttonStyle = { ...styles.button, ...styles.connectedButton };\n } else if (effectiveIsStarting) {\n buttonLabel = (\n <>\n <Spinner />\n Connecting…\n </>\n );\n buttonDisabled = true;\n buttonStyle = { ...styles.button, ...styles.connectButton, ...styles.disabledButton };\n } else {\n // Idle — label depends on strategy\n switch (strategy) {\n case 'passkey':\n buttonLabel = hasPasskeyConfigured ? 'Connect with Passkey' : 'Connect via Passkey';\n if (!isPasskeySupported) {\n buttonLabel = 'Passkey unavailable';\n buttonDisabled = true;\n }\n break;\n case 'password':\n buttonLabel = 'Connect';\n break;\n }\n buttonOnClick = handleConnect;\n buttonStyle = {\n ...styles.button,\n ...styles.connectButton,\n ...(buttonDisabled ? styles.disabledButton : {}),\n };\n }\n\n return (\n <div className={className} style={{ ...styles.root, ...style }} data-fpay-connect-button=\"\">\n {/* Error / passkey unavailability message */}\n {(hasError ||\n (!isPasskeySupported && passkeyUnavailableReason && strategy === 'passkey')) && (\n <span style={styles.errorText}>{error || localError || passkeyUnavailableReason}</span>\n )}\n\n {isRunning ? (\n <div style={{ position: 'relative' }} ref={dropdownRef}>\n <button\n type=\"button\"\n onClick={buttonOnClick}\n style={buttonStyle}\n aria-haspopup=\"dialog\"\n aria-expanded={showDropdown}\n aria-controls={showDropdown ? dropdownId : undefined}\n >\n {buttonLabel}\n </button>\n\n {showDropdown && (\n <div\n id={dropdownId}\n role=\"dialog\"\n aria-label=\"Connection panel\"\n style={{ ...styles.dropdown, ...dropdownStyle }}\n >\n {renderConnectedDropdown ? (\n renderConnectedDropdown({\n fiber,\n closeDropdown,\n disconnect: handleDisconnect,\n })\n ) : (\n <>\n {/* Node info */}\n {nodeInfo && (\n <>\n <div style={styles.infoRow}>\n <span style={styles.infoLabel}>Pubkey</span>\n <span style={styles.infoValue}>{truncateNodeId(nodeInfo.pubkey)}</span>\n </div>\n <div style={styles.infoRow}>\n <span style={styles.infoLabel}>State</span>\n <span style={styles.infoValue}>{state}</span>\n </div>\n </>\n )}\n\n <div style={styles.separator} />\n\n {/* Disconnect */}\n <button\n type=\"button\"\n onClick={() => void handleDisconnect()}\n style={styles.disconnectButton}\n >\n <span>Disconnect</span>\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M9 18l6-6-6-6\" />\n </svg>\n </button>\n </>\n )}\n </div>\n )}\n </div>\n ) : (\n <button type=\"button\" onClick={buttonOnClick} disabled={buttonDisabled} style={buttonStyle}>\n {buttonLabel}\n </button>\n )}\n </div>\n );\n}\n","import {\n type BrowserNodeState,\n FiberBrowserNode,\n type FiberBrowserNodeConfig,\n type FiberWasmFactory,\n type NodeInfoResult,\n PasskeyCredentialProvider,\n type PasskeySupportReason,\n type PasskeySupportStatus,\n PasswordCredentialProvider,\n RawKeyCredentialProvider,\n} from '@fiber-pay/sdk/browser';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nexport interface UseFiberNodeOptions {\n network: 'testnet' | 'mainnet';\n walletId?: string;\n nodeConfig?: FiberBrowserNodeConfig['nodeConfig'];\n wasmFactory?: FiberWasmFactory;\n /** If true, CKB signing key is omitted and external wallet is expected for funding/signing. */\n externalWallet?: boolean;\n /** If false, suppresses initialization effects (like passkey detection). Default true. */\n enabled?: boolean;\n}\n\nexport interface UseFiberNodeResult {\n state: BrowserNodeState;\n node: FiberBrowserNode | null;\n nodeInfo: NodeInfoResult | null;\n error: string | null;\n /** Whether the node is currently starting (unlocking or starting state) */\n isStarting: boolean;\n /** Whether the node is running and ready for RPC calls */\n isRunning: boolean;\n isPasskeySupported: boolean;\n passkeySupportReason: PasskeySupportReason | null;\n passkeyUnavailableReason: string | null;\n hasPasskeyConfigured: boolean;\n startWithPassword: (password: string) => Promise<void>;\n createPasskeyAndStart: (username?: string) => Promise<void>;\n startWithPasskey: () => Promise<void>;\n startWithRawKey: (fiberKey: Uint8Array, ckbSecretKey?: Uint8Array) => Promise<void>;\n stop: () => Promise<void>;\n}\n\nconst PASSKEY_UNAVAILABLE_REASON_TEXT: Record<\n Exclude<PasskeySupportReason, 'supported'>,\n string\n> = {\n 'window-unavailable': 'Passkey is not available because there is no browser window context.',\n 'insecure-context': 'Passkey requires a secure context (HTTPS or localhost).',\n 'webauthn-unavailable': 'This browser does not provide WebAuthn support for passkeys.',\n 'prf-unsupported': 'This browser or authenticator does not support WebAuthn PRF.',\n unknown: 'Passkey support could not be fully detected in this environment.',\n};\n\nexport function isPasskeyPotentiallySupported(status: PasskeySupportStatus): boolean {\n return status.supported || status.reason === 'unknown';\n}\n\nexport function toPasskeyUnavailableReason(reason: PasskeySupportReason): string | null {\n if (reason === 'supported') {\n return null;\n }\n return PASSKEY_UNAVAILABLE_REASON_TEXT[reason];\n}\n\nfunction asErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n\ninterface NodeEventListeners {\n stateChange: (nextState: BrowserNodeState) => void;\n error: (nextError: Error) => void;\n}\n\nexport function useFiberNode(options: UseFiberNodeOptions): UseFiberNodeResult {\n const walletId = options.walletId ?? `wallet-${options.network}`;\n const externalWallet = options.externalWallet ?? false;\n const [state, setState] = useState<BrowserNodeState>('idle');\n const [nodeInfo, setNodeInfo] = useState<NodeInfoResult | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [isPasskeySupported, setIsPasskeySupported] = useState(false);\n const [passkeySupportReason, setPasskeySupportReason] = useState<PasskeySupportReason | null>(\n null,\n );\n const [passkeyUnavailableReason, setPasskeyUnavailableReason] = useState<string | null>(null);\n const [hasPasskeyConfigured, setHasPasskeyConfigured] = useState(false);\n\n const nodeRef = useRef<FiberBrowserNode | null>(null);\n const isMountedRef = useRef(true);\n const nodeListenersRef = useRef<NodeEventListeners | null>(null);\n\n const detachNodeListeners = useCallback((node: FiberBrowserNode | null) => {\n if (!node || !nodeListenersRef.current) {\n return;\n }\n\n node.off('stateChange', nodeListenersRef.current.stateChange);\n node.off('error', nodeListenersRef.current.error);\n nodeListenersRef.current = null;\n }, []);\n\n useEffect(() => {\n // React StrictMode remounts components in development.\n // Reset the mounted flag on each mount so async state updates are not dropped.\n isMountedRef.current = true;\n\n return () => {\n isMountedRef.current = false;\n\n const node = nodeRef.current;\n nodeRef.current = null;\n\n if (node) {\n detachNodeListeners(node);\n void node.stop().catch(() => {});\n }\n };\n }, [detachNodeListeners]);\n\n useEffect(() => {\n if (options.enabled === false) return;\n let cancelled = false;\n\n PasskeyCredentialProvider.getSupportStatus()\n .then((status) => {\n if (!cancelled) {\n const supported = isPasskeyPotentiallySupported(status);\n setIsPasskeySupported(supported);\n setPasskeySupportReason(status.reason);\n setPasskeyUnavailableReason(supported ? null : toPasskeyUnavailableReason(status.reason));\n }\n })\n .catch((supportError) => {\n if (!cancelled) {\n setIsPasskeySupported(false);\n setPasskeySupportReason('unknown');\n setPasskeyUnavailableReason(toPasskeyUnavailableReason('unknown'));\n }\n\n if (supportError instanceof Error) {\n console.warn('[fiber-pay/react] Failed to detect passkey support:', supportError.message);\n }\n });\n\n const provider = new PasskeyCredentialProvider(walletId, { skipCkbKey: externalWallet });\n setHasPasskeyConfigured(provider.isConfigured());\n\n return () => {\n cancelled = true;\n };\n }, [walletId, options.enabled, externalWallet]);\n\n const initNode = useCallback(\n (\n credential: PasswordCredentialProvider | PasskeyCredentialProvider | RawKeyCredentialProvider,\n ) => {\n if (nodeRef.current) {\n const existingState = nodeRef.current.state;\n if (existingState !== 'idle' && existingState !== 'stopped' && existingState !== 'error') {\n throw new Error('Node already running');\n }\n\n detachNodeListeners(nodeRef.current);\n nodeRef.current = null;\n }\n\n const nodeConfig: ConstructorParameters<typeof FiberBrowserNode>[0] = {\n network: options.network,\n credential,\n nodeConfig: {\n databasePrefix: `/${walletId}`,\n ...(options.nodeConfig ?? {}),\n },\n };\n\n if (options.wasmFactory) {\n nodeConfig.wasmFactory = options.wasmFactory;\n }\n\n const node = new FiberBrowserNode(nodeConfig);\n\n nodeRef.current = node;\n\n const listeners: NodeEventListeners = {\n stateChange: (nextState) => {\n if (!isMountedRef.current) {\n return;\n }\n\n setState(nextState);\n if (nextState === 'stopped') {\n setNodeInfo(null);\n }\n },\n error: (nextError: Error) => {\n if (!isMountedRef.current) {\n return;\n }\n\n setError(nextError.message);\n },\n };\n\n nodeListenersRef.current = listeners;\n node.on('stateChange', listeners.stateChange);\n node.on('error', listeners.error);\n\n return node;\n },\n [detachNodeListeners, options.network, options.nodeConfig, options.wasmFactory, walletId],\n );\n\n const cleanupFailedStart = useCallback(\n async (node: FiberBrowserNode | null) => {\n if (!node) {\n return;\n }\n\n try {\n if (node.state !== 'idle' && node.state !== 'stopped') {\n await node.stop();\n }\n } catch {\n // Ignore cleanup failures after a start error.\n } finally {\n detachNodeListeners(node);\n if (nodeRef.current === node) {\n nodeRef.current = null;\n }\n }\n },\n [detachNodeListeners],\n );\n\n const startWithPassword = useCallback(\n async (password: string) => {\n setError(null);\n let node: FiberBrowserNode | null = null;\n\n try {\n const credential = new PasswordCredentialProvider(walletId, {\n skipCkbKey: externalWallet,\n });\n node = initNode(credential);\n const info = await node.start({ unlockParams: { password } });\n if (isMountedRef.current) {\n setNodeInfo(info);\n }\n } catch (startError) {\n if (isMountedRef.current) {\n setError(asErrorMessage(startError));\n }\n\n await cleanupFailedStart(node);\n }\n },\n [cleanupFailedStart, initNode, walletId, externalWallet],\n );\n\n const createPasskeyAndStart = useCallback(\n async (username = 'User') => {\n setError(null);\n let node: FiberBrowserNode | null = null;\n\n try {\n const credential = new PasskeyCredentialProvider(walletId, {\n skipCkbKey: externalWallet,\n });\n await credential.register(username);\n if (isMountedRef.current) {\n setHasPasskeyConfigured(true);\n }\n\n node = initNode(credential);\n const info = await node.start();\n if (isMountedRef.current) {\n setNodeInfo(info);\n }\n } catch (startError) {\n if (isMountedRef.current) {\n setError(asErrorMessage(startError));\n }\n\n await cleanupFailedStart(node);\n }\n },\n [cleanupFailedStart, initNode, walletId, externalWallet],\n );\n\n const startWithPasskey = useCallback(async () => {\n setError(null);\n let node: FiberBrowserNode | null = null;\n\n try {\n const credential = new PasskeyCredentialProvider(walletId, {\n skipCkbKey: externalWallet,\n });\n node = initNode(credential);\n const info = await node.start();\n if (isMountedRef.current) {\n setNodeInfo(info);\n }\n } catch (startError) {\n if (isMountedRef.current) {\n setError(asErrorMessage(startError));\n }\n\n await cleanupFailedStart(node);\n }\n }, [cleanupFailedStart, initNode, walletId, externalWallet]);\n\n const startWithRawKey = useCallback(\n async (fiberKey: Uint8Array, ckbSecretKey?: Uint8Array) => {\n setError(null);\n let node: FiberBrowserNode | null = null;\n\n try {\n const credential = new RawKeyCredentialProvider(\n fiberKey,\n externalWallet ? undefined : ckbSecretKey,\n walletId,\n );\n node = initNode(credential);\n const info = await node.start();\n if (isMountedRef.current) {\n setNodeInfo(info);\n }\n } catch (startError) {\n if (isMountedRef.current) {\n setError(asErrorMessage(startError));\n }\n\n await cleanupFailedStart(node);\n }\n },\n [cleanupFailedStart, initNode, walletId, externalWallet],\n );\n\n const stop = useCallback(async () => {\n const node = nodeRef.current;\n if (!node) {\n return;\n }\n\n try {\n await node.stop();\n } catch (stopError) {\n if (isMountedRef.current) {\n setError(asErrorMessage(stopError));\n }\n } finally {\n detachNodeListeners(node);\n if (nodeRef.current === node) {\n nodeRef.current = null;\n }\n\n if (isMountedRef.current) {\n setNodeInfo(null);\n }\n }\n }, [detachNodeListeners]);\n\n const isStarting = useMemo(() => state === 'unlocking' || state === 'starting', [state]);\n const isRunning = useMemo(() => state === 'running', [state]);\n\n return {\n state,\n node: nodeRef.current,\n nodeInfo,\n error,\n isStarting,\n isRunning,\n isPasskeySupported,\n passkeySupportReason,\n passkeyUnavailableReason,\n hasPasskeyConfigured,\n startWithPassword,\n createPasskeyAndStart,\n startWithPasskey,\n startWithRawKey,\n stop,\n };\n}\n","import { useCallback } from 'react';\nimport { ConnectButton, type ConnectButtonConnectedDropdownContext } from '../connect-button.js';\nimport { useFiberNode } from '../use-fiber-node.js';\nimport { FiberNodeButtonPanel } from './panel.js';\nimport type { FiberNodeButtonProps } from './types.js';\n\nexport type {\n FiberNodeButtonActionDefaultProps,\n FiberNodeButtonActionId,\n FiberNodeButtonConnectorSectionContext,\n FiberNodeButtonExternalFundingConfig,\n FiberNodeButtonExternalFundingResolved,\n FiberNodeButtonExternalFundingResolverContext,\n FiberNodeButtonI18n,\n FiberNodeButtonProps,\n FiberNodeButtonRenderAction,\n FiberNodeButtonRenderActionContext,\n FiberNodeButtonTabActions,\n FiberNodeButtonTabConfig,\n FiberNodeButtonTabContext,\n FiberNodeButtonTabId,\n} from './types.js';\n\nexport function FiberNodeButton(props: FiberNodeButtonProps) {\n const {\n network = 'testnet',\n fiber: externalFiber,\n strategy = 'passkey',\n externalWallet = false,\n password,\n walletId,\n passkeyUsername = 'User',\n wasmFactory,\n nodeConfig,\n className,\n style,\n dropdownStyle,\n onConnect,\n onDisconnect,\n onError,\n onLog,\n initialPeerPubkey = '',\n initialPeerAddress = '',\n initialFundingAmountCkb = '1000',\n externalFunding,\n renderConnectorSection,\n tabs,\n renderTabContent,\n renderAction,\n t,\n } = props;\n\n const managedFiber = useFiberNode({\n network,\n walletId,\n wasmFactory,\n nodeConfig,\n externalWallet,\n enabled: !externalFiber,\n });\n\n const fiber = externalFiber ?? managedFiber;\n\n const handleConnectButtonError = useCallback(\n (error: string) => {\n onError?.(error);\n },\n [onError],\n );\n\n const renderDropdown = useCallback(\n (dropdownContext: ConnectButtonConnectedDropdownContext) => (\n <FiberNodeButtonPanel\n dropdownContext={dropdownContext}\n network={network}\n fiber={fiber}\n onLog={onLog}\n onError={onError}\n initialPeerPubkey={initialPeerPubkey}\n initialPeerAddress={initialPeerAddress}\n initialFundingAmountCkb={initialFundingAmountCkb}\n externalFunding={externalFunding}\n renderConnectorSection={renderConnectorSection}\n tabs={tabs}\n renderTabContent={renderTabContent}\n renderAction={renderAction}\n t={t}\n />\n ),\n [\n externalFunding,\n fiber,\n initialFundingAmountCkb,\n initialPeerAddress,\n initialPeerPubkey,\n network,\n onError,\n onLog,\n renderAction,\n renderConnectorSection,\n renderTabContent,\n t,\n tabs,\n ],\n );\n\n return (\n <ConnectButton\n fiber={fiber}\n strategy={strategy}\n password={password}\n passkeyUsername={passkeyUsername}\n onConnect={onConnect}\n onDisconnect={onDisconnect}\n onError={handleConnectButtonError}\n className={className}\n style={style}\n dropdownStyle={{ maxWidth: 460, width: 'calc(100vw - 1rem)', ...dropdownStyle }}\n renderConnectedDropdown={renderDropdown}\n />\n );\n}\n","import { useEffect, useMemo, useRef } from 'react';\nimport { ChannelsTab } from './channels-tab.js';\nimport { DiagnosticsTab } from './diagnostics-tab.js';\nimport { defaultFiberNodeButtonI18n } from './i18n.js';\nimport { styles } from './styles.js';\nimport {\n type FiberNodeButtonPanelProps,\n type FiberNodeButtonTabConfig,\n type FiberNodeButtonTabContext,\n type FiberNodeButtonTabId,\n TAB_ITEMS,\n} from './types.js';\nimport { useFiberNodeButtonPanelState } from './use-panel-state.js';\nimport { shorten, summarizeError } from './utils.js';\nimport { WorkbenchTab } from './workbench-tab.js';\n\ninterface ResolvedTabItem {\n id: FiberNodeButtonTabId;\n domId: string;\n label: string;\n render?: FiberNodeButtonTabConfig['render'];\n}\n\nfunction toDomSafeTabId(tabId: FiberNodeButtonTabId, index: number): string {\n const normalized = tabId\n .trim()\n .replace(/[^A-Za-z0-9_-]+/g, '-')\n .replace(/^-+|-+$/g, '');\n\n const safeBase = normalized.length > 0 ? normalized : 'tab';\n return `${safeBase}-${index + 1}`;\n}\n\nfunction resolveTabLabel(tabId: FiberNodeButtonTabId, t: FiberNodeButtonTabContext['t']): string {\n const builtIn = TAB_ITEMS.find((item) => item.id === tabId);\n if (!builtIn) {\n return tabId;\n }\n\n if (builtIn.id === 'workbench') {\n return t('tabs.workbench', builtIn.label);\n }\n if (builtIn.id === 'channels') {\n return t('tabs.channels', builtIn.label);\n }\n return t('tabs.diagnostics', builtIn.label);\n}\n\nfunction resolveTabs(\n tabs: ReadonlyArray<FiberNodeButtonTabConfig> | undefined,\n t: FiberNodeButtonTabContext['t'],\n): ResolvedTabItem[] {\n const defaultIds = TAB_ITEMS.map((item) => item.id);\n\n if (!tabs || tabs.length === 0) {\n return defaultIds.map((id, index) => ({\n id,\n domId: toDomSafeTabId(id, index),\n label: resolveTabLabel(id, t),\n }));\n }\n\n const tabConfigById = new Map<FiberNodeButtonTabId, FiberNodeButtonTabConfig>();\n const orderedIds: FiberNodeButtonTabId[] = [];\n\n for (const tabConfig of tabs) {\n tabConfigById.set(tabConfig.id, tabConfig);\n if (!orderedIds.includes(tabConfig.id)) {\n orderedIds.push(tabConfig.id);\n }\n }\n\n for (const id of defaultIds) {\n if (!orderedIds.includes(id)) {\n orderedIds.push(id);\n }\n }\n\n const resolvedTabs: ResolvedTabItem[] = [];\n\n for (const [index, id] of orderedIds.entries()) {\n const config = tabConfigById.get(id);\n if (config?.hidden) {\n continue;\n }\n\n const label =\n typeof config?.label === 'function'\n ? config.label(t)\n : (config?.label ?? resolveTabLabel(id, t));\n\n const tabItem: ResolvedTabItem = {\n id,\n domId: toDomSafeTabId(id, index),\n label,\n };\n\n if (config?.render) {\n tabItem.render = config.render;\n }\n\n resolvedTabs.push(tabItem);\n }\n\n return resolvedTabs;\n}\n\nexport function FiberNodeButtonPanel(props: FiberNodeButtonPanelProps) {\n const {\n dropdownContext,\n fiber,\n onLog,\n externalFunding,\n renderConnectorSection,\n tabs,\n renderTabContent,\n renderAction,\n } = props;\n const t = props.t ?? defaultFiberNodeButtonI18n;\n const state = useFiberNodeButtonPanelState(props);\n const forceCloseDialogRef = useRef<HTMLDivElement | null>(null);\n\n const {\n activeTab,\n switchTab,\n tabPanelId,\n statusNotice,\n latestError,\n activeChannelCount,\n connectedPeers,\n forceCloseConfirmOpen,\n setForceCloseConfirmOpen,\n selectedChannel,\n closeChannel,\n openChannel,\n createInvoice,\n submitPayment,\n } = state;\n\n const tabActions = useMemo<FiberNodeButtonTabContext['actions']>(\n () => ({\n openChannel: async () => {\n await openChannel();\n },\n createInvoice: async () => {\n await createInvoice();\n },\n payInvoice: async () => {\n await submitPayment();\n },\n closeChannel: async (channelId: string) => {\n await closeChannel(channelId, false);\n },\n forceCloseChannel: async (channelId: string) => {\n await closeChannel(channelId, true);\n },\n }),\n [closeChannel, createInvoice, openChannel, submitPayment],\n );\n\n const tabContext = useMemo<FiberNodeButtonTabContext>(\n () => ({\n fiber,\n state,\n externalFundingEnabled: !!externalFunding?.enabled,\n t,\n actions: tabActions,\n }),\n [externalFunding?.enabled, fiber, state, t, tabActions],\n );\n\n const resolvedTabs = useMemo(() => resolveTabs(tabs, t), [t, tabs]);\n\n const effectiveActiveTab = useMemo(\n () =>\n resolvedTabs.some((tab) => tab.id === activeTab) ? activeTab : (resolvedTabs[0]?.id ?? null),\n [activeTab, resolvedTabs],\n );\n\n const selectedResolvedTab = useMemo(\n () => resolvedTabs.find((tab) => tab.id === effectiveActiveTab) ?? null,\n [effectiveActiveTab, resolvedTabs],\n );\n\n const tabListStyle = useMemo(\n () => ({\n ...styles.tabList,\n gridTemplateColumns: `repeat(${Math.max(1, resolvedTabs.length)}, minmax(112px, 1fr))`,\n overflowX: 'auto' as const,\n }),\n [resolvedTabs.length],\n );\n\n const overriddenTabContent = effectiveActiveTab\n ? renderTabContent?.(effectiveActiveTab, tabContext)\n : undefined;\n\n let tabContent = overriddenTabContent;\n if (tabContent === undefined) {\n if (selectedResolvedTab?.render) {\n tabContent = selectedResolvedTab.render(tabContext);\n } else if (effectiveActiveTab === 'workbench') {\n tabContent = (\n <WorkbenchTab\n state={state}\n fiber={fiber}\n externalFunding={externalFunding}\n renderConnectorSection={renderConnectorSection}\n renderAction={renderAction}\n t={t}\n />\n );\n } else if (effectiveActiveTab === 'channels') {\n tabContent = (\n <ChannelsTab state={state} onLog={onLog} renderAction={renderAction} t={t} fiber={fiber} />\n );\n } else if (effectiveActiveTab === 'diagnostics') {\n tabContent = <DiagnosticsTab state={state} t={t} />;\n } else if (effectiveActiveTab === null) {\n tabContent = (\n <div style={styles.notice}>{t('tabs.empty', 'No visible tabs are configured.')}</div>\n );\n } else {\n tabContent = (\n <div style={styles.notice}>\n {t('tabs.unimplemented', 'Tab content is not implemented.')}\n </div>\n );\n }\n }\n\n useEffect(() => {\n if (forceCloseConfirmOpen) {\n forceCloseDialogRef.current?.focus();\n }\n }, [forceCloseConfirmOpen]);\n\n useEffect(() => {\n if (resolvedTabs.length === 0) {\n return;\n }\n if (!resolvedTabs.some((tab) => tab.id === activeTab)) {\n switchTab(resolvedTabs[0].id);\n }\n }, [activeTab, resolvedTabs, switchTab]);\n\n return (\n <div style={styles.shell}>\n <header style={styles.globalBar}>\n <div style={styles.globalRow}>\n <div style={styles.globalMetrics}>\n <span style={styles.metricInline}>\n <span\n style={{\n ...styles.metricDot,\n background:\n fiber.state === 'running'\n ? '#16a34a'\n : fiber.state === 'error'\n ? '#dc2626'\n : '#64748b',\n }}\n aria-hidden=\"true\"\n />\n <span style={styles.metricMain}>{fiber.state}</span>\n <span style={styles.metricSub}>{t('metrics.node', 'Node')}</span>\n </span>\n\n <span style={styles.metricDivider} aria-hidden=\"true\">\n |\n </span>\n\n <span style={styles.metricInline}>\n <span style={styles.metricMain}>\n {externalFunding?.enabled\n ? t('metrics.funding.external', 'External')\n : t('metrics.funding.internal', 'Internal')}\n </span>\n <span style={styles.metricSub}>{t('metrics.funding', 'Funding')}</span>\n </span>\n\n <span style={styles.metricDivider} aria-hidden=\"true\">\n |\n </span>\n\n <span style={styles.metricInline}>\n <span style={styles.metricMain}>{activeChannelCount}</span>\n <span style={styles.metricSub}>{t('metrics.active', 'Active')}</span>\n </span>\n\n <span style={styles.metricDivider} aria-hidden=\"true\">\n |\n </span>\n\n <span style={styles.metricInline}>\n <span style={styles.metricMain}>{connectedPeers.length}</span>\n <span style={styles.metricSub}>{t('metrics.peers', 'Peers')}</span>\n </span>\n\n {latestError ? (\n <>\n <span style={styles.metricDivider} aria-hidden=\"true\">\n |\n </span>\n <span style={styles.metricInline}>\n <span\n style={{\n ...styles.metricDot,\n background: '#dc2626',\n }}\n aria-hidden=\"true\"\n />\n <span style={styles.metricMain}>{t('metrics.error', 'Error')}</span>\n </span>\n </>\n ) : null}\n </div>\n\n <div style={styles.globalActions}>\n <button\n type=\"button\"\n style={styles.globalActionButton}\n onClick={() => {\n void dropdownContext.disconnect();\n }}\n aria-label={t('actions.disconnect.aria', 'Disconnect node')}\n >\n {t('actions.disconnect', 'Disconnect')}\n </button>\n <button\n type=\"button\"\n style={styles.globalActionButton}\n onClick={() => {\n dropdownContext.closeDropdown();\n }}\n aria-label={t('actions.closePanel.aria', 'Close panel')}\n >\n {t('actions.closePanel', 'Close Panel')}\n </button>\n </div>\n </div>\n\n <div style={styles.globalMeta}>\n <p style={styles.inlineCode}>\n {t('meta.node', 'Node')}:{' '}\n {fiber.nodeInfo?.pubkey ? shorten(fiber.nodeInfo.pubkey, 18, 12) : t('meta.na', 'N/A')}\n </p>\n {latestError ? (\n <p style={styles.globalErrorInline}>\n {t('meta.recentError', 'Recent error')}: {summarizeError(latestError, 92)}\n </p>\n ) : null}\n </div>\n </header>\n\n <div role=\"tablist\" aria-label={t('tabs.aria', 'Fiber panel tabs')} style={tabListStyle}>\n {resolvedTabs.map((tab) => {\n const selected = effectiveActiveTab === tab.id;\n return (\n <button\n key={tab.id}\n id={`${tabPanelId}-tab-${tab.domId}`}\n type=\"button\"\n role=\"tab\"\n aria-selected={selected}\n aria-controls={selected ? `${tabPanelId}-panel-${tab.domId}` : undefined}\n style={selected ? styles.tabButtonActive : styles.tabButton}\n onClick={() => switchTab(tab.id)}\n >\n {tab.label}\n </button>\n );\n })}\n </div>\n\n <div\n id={`${tabPanelId}-panel-${selectedResolvedTab?.domId ?? 'empty'}`}\n role=\"tabpanel\"\n aria-labelledby={\n selectedResolvedTab ? `${tabPanelId}-tab-${selectedResolvedTab.domId}` : undefined\n }\n style={styles.content}\n >\n {statusNotice ? (\n <div\n style={{\n ...styles.notice,\n ...(statusNotice.tone === 'success' ? styles.successNotice : {}),\n }}\n >\n {statusNotice.text}\n </div>\n ) : null}\n\n {tabContent}\n\n {latestError ? <div style={styles.errorNotice}>{latestError}</div> : null}\n </div>\n\n {forceCloseConfirmOpen && selectedChannel ? (\n <div style={styles.dialogBackdrop}>\n <div\n ref={forceCloseDialogRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={t('dialog.forceClose.aria', 'Force close confirmation')}\n tabIndex={-1}\n style={styles.dialogCard}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n setForceCloseConfirmOpen(false);\n }\n }}\n >\n <h4 style={styles.sectionTitle}>\n {t('dialog.forceClose.title', 'Force close this channel?')}\n </h4>\n <p style={styles.compactText}>\n {t(\n 'dialog.forceClose.description',\n 'This action may immediately broadcast a unilateral close transaction, can lock liquidity until settlement, and may produce additional fees. Continue only if normal close cannot proceed.',\n )}\n </p>\n <p style={styles.inlineCode}>\n {t('dialog.forceClose.channel', 'Channel')}:{' '}\n {shorten(selectedChannel.channel_id, 20, 12)}\n </p>\n <div style={{ ...styles.row, justifyContent: 'flex-end' }}>\n <button\n type=\"button\"\n style={styles.actionButton}\n onClick={() => {\n setForceCloseConfirmOpen(false);\n }}\n >\n {t('dialog.forceClose.cancel', 'Cancel')}\n </button>\n <button\n type=\"button\"\n style={styles.dangerButton}\n onClick={() => {\n setForceCloseConfirmOpen(false);\n onLog?.('fiber_channel_force_close_confirmed');\n void closeChannel(selectedChannel.channel_id, true);\n }}\n >\n {t('dialog.forceClose.confirm', 'Confirm Force Close')}\n </button>\n </div>\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n","import type { CSSProperties } from 'react';\n\nexport const styles = {\n shell: {\n position: 'relative',\n display: 'grid',\n gridTemplateRows: 'auto auto minmax(0, 1fr)',\n gap: '0.7rem',\n minWidth: '280px',\n width: 'min(460px, calc(100vw - 1rem))',\n maxHeight: '72vh',\n } satisfies CSSProperties,\n\n globalBar: {\n border: '1px solid var(--fpay-border, #d8dee8)',\n borderRadius: '0.72rem',\n background: 'linear-gradient(180deg, #ffffff 0%, #f8fafc 100%)',\n padding: '0.52rem 0.56rem',\n display: 'grid',\n gap: '0.45rem',\n } satisfies CSSProperties,\n\n globalRow: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '0.35rem',\n flexWrap: 'wrap',\n } satisfies CSSProperties,\n\n globalMetrics: {\n display: 'flex',\n alignItems: 'center',\n gap: '0.5rem',\n flexWrap: 'wrap',\n minWidth: 0,\n } satisfies CSSProperties,\n\n metricInline: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '0.24rem',\n whiteSpace: 'nowrap',\n } satisfies CSSProperties,\n\n metricDot: {\n display: 'inline-flex',\n width: '0.34rem',\n height: '0.34rem',\n borderRadius: '999px',\n flexShrink: 0,\n background: '#94a3b8',\n } satisfies CSSProperties,\n\n metricMain: {\n fontSize: '0.82rem',\n fontWeight: 750,\n color: 'var(--fpay-text-primary, #0f172a)',\n lineHeight: 1.1,\n } satisfies CSSProperties,\n\n metricSub: {\n fontSize: '0.72rem',\n color: 'var(--fpay-text-secondary, #64748b)',\n lineHeight: 1.1,\n } satisfies CSSProperties,\n\n metricDivider: {\n fontSize: '0.7rem',\n color: '#94a3b8',\n lineHeight: 1,\n } satisfies CSSProperties,\n\n globalMeta: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '0.5rem',\n flexWrap: 'wrap',\n } satisfies CSSProperties,\n\n globalErrorInline: {\n margin: 0,\n fontSize: '0.71rem',\n color: '#9f1239',\n lineHeight: 1.25,\n } satisfies CSSProperties,\n\n statusDot: {\n display: 'inline-flex',\n width: '0.45rem',\n height: '0.45rem',\n borderRadius: '999px',\n flexShrink: 0,\n } satisfies CSSProperties,\n\n globalActions: {\n display: 'flex',\n gap: '0.36rem',\n justifyContent: 'flex-end',\n flexWrap: 'wrap',\n } satisfies CSSProperties,\n\n globalActionButton: {\n border: '1px solid var(--fpay-border, #cbd5e1)',\n borderRadius: '0.45rem',\n padding: '0.28rem 0.48rem',\n fontSize: '0.72rem',\n fontWeight: 650,\n background: '#fff',\n color: 'var(--fpay-text-primary, #111827)',\n cursor: 'pointer',\n } satisfies CSSProperties,\n\n tabList: {\n borderRadius: '0.68rem',\n border: 'none',\n background: '#e9eef6',\n padding: '0.14rem',\n display: 'grid',\n gridTemplateColumns: 'repeat(3, minmax(0, 1fr))',\n gap: '0.14rem',\n boxShadow: 'inset 0 0 0 1px var(--fpay-border, #d8dee8)',\n } satisfies CSSProperties,\n\n tabButton: {\n border: 'none',\n borderRadius: '0.5rem',\n background: 'transparent',\n color: '#334155',\n fontSize: '0.74rem',\n fontWeight: 700,\n padding: '0.44rem 0.45rem',\n cursor: 'pointer',\n } satisfies CSSProperties,\n\n tabButtonActive: {\n border: 'none',\n borderRadius: '0.5rem',\n background: 'var(--fpay-accent, #1d4ed8)',\n color: '#fff',\n fontSize: '0.74rem',\n fontWeight: 700,\n padding: '0.44rem 0.45rem',\n cursor: 'pointer',\n boxShadow: 'none',\n } satisfies CSSProperties,\n\n content: {\n overflowY: 'auto',\n paddingRight: '0.15rem',\n display: 'grid',\n gap: '0.7rem',\n minHeight: 0,\n } satisfies CSSProperties,\n\n section: {\n border: 'none',\n borderBottom: '1px solid var(--fpay-border, #e2e8f0)',\n borderRadius: 0,\n padding: '0.15rem 0 0.55rem',\n background: 'transparent',\n display: 'grid',\n gap: '0.44rem',\n } satisfies CSSProperties,\n\n sectionTitle: {\n margin: 0,\n fontSize: '0.8rem',\n fontWeight: 750,\n color: 'var(--fpay-text-primary, #0f172a)',\n letterSpacing: '0.01em',\n } satisfies CSSProperties,\n\n row: {\n display: 'flex',\n alignItems: 'center',\n gap: '0.45rem',\n flexWrap: 'wrap',\n } satisfies CSSProperties,\n\n rowBetween: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '0.45rem',\n flexWrap: 'wrap',\n } satisfies CSSProperties,\n\n compactText: {\n margin: 0,\n fontSize: '0.74rem',\n color: 'var(--fpay-text-secondary, #64748b)',\n lineHeight: 1.4,\n } satisfies CSSProperties,\n\n inlineCode: {\n margin: 0,\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',\n fontSize: '0.72rem',\n color: 'var(--fpay-text-primary, #111827)',\n wordBreak: 'break-all',\n lineHeight: 1.4,\n } satisfies CSSProperties,\n\n fieldLabel: {\n display: 'grid',\n gap: '0.25rem',\n fontSize: '0.68rem',\n fontWeight: 700,\n color: 'var(--fpay-text-secondary, #64748b)',\n textTransform: 'uppercase',\n } satisfies CSSProperties,\n\n input: {\n width: '100%',\n border: '1px solid var(--fpay-border, #cbd5e1)',\n borderRadius: '0.45rem',\n padding: '0.38rem 0.48rem',\n fontSize: '0.8rem',\n background: '#fff',\n color: 'var(--fpay-text-primary, #0f172a)',\n } satisfies CSSProperties,\n\n actionButton: {\n border: '1px solid var(--fpay-border, #cbd5e1)',\n borderRadius: '0.45rem',\n padding: '0.35rem 0.55rem',\n fontSize: '0.74rem',\n fontWeight: 650,\n background: '#fff',\n color: 'var(--fpay-text-primary, #111827)',\n cursor: 'pointer',\n } satisfies CSSProperties,\n\n primaryButton: {\n border: '1px solid var(--fpay-accent, #1d4ed8)',\n borderRadius: '0.45rem',\n padding: '0.35rem 0.55rem',\n fontSize: '0.74rem',\n fontWeight: 750,\n background: 'var(--fpay-accent, #1d4ed8)',\n color: '#fff',\n cursor: 'pointer',\n } satisfies CSSProperties,\n\n ghostButton: {\n border: '1px solid transparent',\n borderRadius: '0.45rem',\n padding: '0.32rem 0.5rem',\n fontSize: '0.74rem',\n fontWeight: 650,\n background: 'transparent',\n color: 'var(--fpay-text-secondary, #475569)',\n cursor: 'pointer',\n } satisfies CSSProperties,\n\n dangerButton: {\n border: '1px solid #fecaca',\n borderRadius: '0.45rem',\n padding: '0.35rem 0.55rem',\n fontSize: '0.74rem',\n fontWeight: 750,\n background: '#fff1f2',\n color: '#9f1239',\n cursor: 'pointer',\n } satisfies CSSProperties,\n\n badge: {\n display: 'inline-flex',\n alignItems: 'center',\n width: 'fit-content',\n borderRadius: '999px',\n border: '1px solid var(--fpay-border, #cbd5e1)',\n background: '#f8fafc',\n color: 'var(--fpay-text-secondary, #475569)',\n padding: '0.12rem 0.4rem',\n fontSize: '0.66rem',\n fontWeight: 700,\n lineHeight: 1.1,\n } satisfies CSSProperties,\n\n notice: {\n border: '1px solid #bfdbfe',\n background: '#eff6ff',\n color: '#1d4ed8',\n borderRadius: '0.52rem',\n padding: '0.46rem 0.52rem',\n fontSize: '0.74rem',\n lineHeight: 1.35,\n } satisfies CSSProperties,\n\n successNotice: {\n borderColor: '#86efac',\n background: '#f0fdf4',\n color: '#166534',\n } satisfies CSSProperties,\n\n errorNotice: {\n border: '1px solid #fecaca',\n background: '#fff1f2',\n color: '#9f1239',\n borderRadius: '0.52rem',\n padding: '0.46rem 0.52rem',\n fontSize: '0.74rem',\n lineHeight: 1.35,\n } satisfies CSSProperties,\n\n summaryGrid: {\n display: 'none',\n } satisfies CSSProperties,\n\n summaryTile: {\n display: 'none',\n } satisfies CSSProperties,\n\n summaryValue: {\n display: 'block',\n fontSize: '0.92rem',\n fontWeight: 750,\n color: 'var(--fpay-text-primary, #0f172a)',\n lineHeight: 1.1,\n } satisfies CSSProperties,\n\n summaryLabel: {\n display: 'block',\n marginTop: '0.12rem',\n fontSize: '0.64rem',\n color: 'var(--fpay-text-secondary, #64748b)',\n } satisfies CSSProperties,\n\n summaryInline: {\n margin: 0,\n fontSize: '0.76rem',\n color: 'var(--fpay-text-secondary, #475569)',\n lineHeight: 1.35,\n } satisfies CSSProperties,\n\n filterBar: {\n display: 'flex',\n flexWrap: 'wrap',\n gap: '0.28rem',\n } satisfies CSSProperties,\n\n list: {\n display: 'grid',\n gap: '0.34rem',\n maxHeight: '240px',\n overflowY: 'auto',\n paddingRight: '0.1rem',\n } satisfies CSSProperties,\n\n compactChannelRow: {\n border: '1px solid var(--fpay-border, #d8dee8)',\n borderRadius: '0.5rem',\n background: '#fff',\n padding: '0.42rem 0.46rem',\n cursor: 'pointer',\n display: 'grid',\n gap: '0.22rem',\n textAlign: 'left',\n } satisfies CSSProperties,\n\n compactChannelRowActive: {\n borderColor: 'var(--fpay-accent, #1d4ed8)',\n boxShadow: '0 0 0 1px rgba(29, 78, 216, 0.12) inset',\n background: '#f8fbff',\n } satisfies CSSProperties,\n\n compactChannelTop: {\n display: 'grid',\n gridTemplateColumns: '1fr auto',\n alignItems: 'center',\n gap: '0.35rem',\n } satisfies CSSProperties,\n\n detailPanel: {\n border: '1px solid var(--fpay-border, #d8dee8)',\n borderRadius: '0.6rem',\n background: '#f8fafc',\n padding: '0.6rem',\n display: 'grid',\n gap: '0.45rem',\n } satisfies CSSProperties,\n\n dialogBackdrop: {\n position: 'absolute',\n inset: 0,\n background: 'rgba(15, 23, 42, 0.36)',\n display: 'grid',\n placeItems: 'center',\n padding: '0.75rem',\n zIndex: 3,\n } satisfies CSSProperties,\n\n dialogCard: {\n width: 'min(100%, 360px)',\n borderRadius: '0.68rem',\n border: '1px solid #fecaca',\n background: '#fff',\n padding: '0.72rem',\n display: 'grid',\n gap: '0.55rem',\n } satisfies CSSProperties,\n\n srOnly: {\n position: 'absolute',\n width: 1,\n height: 1,\n padding: 0,\n margin: -1,\n overflow: 'hidden',\n clip: 'rect(0, 0, 0, 0)',\n border: 0,\n } satisfies CSSProperties,\n};\n","import type { Channel, HexString } from '@fiber-pay/sdk/browser';\nimport { ChannelState, shannonsToCkb } from '@fiber-pay/sdk/browser';\nimport type { CSSProperties } from 'react';\nimport type { ChannelFilter } from './types.js';\n\nexport function shorten(value: string, head = 10, tail = 8): string {\n if (!value || value.length <= head + tail + 3) {\n return value;\n }\n return `${value.slice(0, head)}...${value.slice(-tail)}`;\n}\n\nexport function summarizeError(message: string, max = 72): string {\n const trimmed = message.trim();\n if (trimmed.length <= max) {\n return trimmed;\n }\n return `${trimmed.slice(0, max - 3)}...`;\n}\n\nexport function toHexPrefixed(value: string): HexString {\n const trimmed = value.trim();\n if (!trimmed) {\n throw new Error('Hex value is empty.');\n }\n return (/^0x/i.test(trimmed) ? trimmed : `0x${trimmed}`) as HexString;\n}\n\nexport function isPendingChannelState(state: ChannelState): boolean {\n return (\n state === ChannelState.NegotiatingFunding ||\n state === ChannelState.CollaboratingFundingTx ||\n state === ChannelState.SigningCommitment ||\n state === ChannelState.AwaitingTxSignatures ||\n state === ChannelState.AwaitingChannelReady\n );\n}\n\nexport function formatChannelBalance(shannonsHex: HexString): string {\n const ckb = shannonsToCkb(shannonsHex);\n return Number.isFinite(ckb) ? ckb.toFixed(4) : '0.0000';\n}\n\nexport function isClosedChannelState(state: ChannelState): boolean {\n return state === ChannelState.Closed || state === ChannelState.ShuttingDown;\n}\n\nexport function getChannelFilterState(channel: Channel): ChannelFilter {\n const state = channel.state.state_name;\n if (isPendingChannelState(state)) return 'pending';\n if (isClosedChannelState(state)) return 'closed';\n return 'active';\n}\n\nexport function withDisabledStyle(style: CSSProperties, disabled: boolean): CSSProperties {\n if (!disabled) {\n return style;\n }\n return {\n ...style,\n opacity: 0.55,\n cursor: 'not-allowed',\n };\n}\n","import type { CSSProperties, ReactNode } from 'react';\nimport type { UseFiberNodeResult } from '../use-fiber-node.js';\nimport { styles } from './styles.js';\nimport type {\n FiberNodeButtonActionDefaultProps,\n FiberNodeButtonActionId,\n FiberNodeButtonI18n,\n FiberNodeButtonRenderAction,\n} from './types.js';\nimport type { FiberNodeButtonPanelState } from './use-panel-state.js';\nimport { withDisabledStyle } from './utils.js';\n\nexport interface RenderPanelActionOptions {\n id: FiberNodeButtonActionId;\n defaultProps: FiberNodeButtonActionDefaultProps;\n fiber: UseFiberNodeResult;\n state: FiberNodeButtonPanelState;\n renderAction?: FiberNodeButtonRenderAction;\n t: FiberNodeButtonI18n;\n buttonStyle?: CSSProperties;\n}\n\nexport function renderPanelAction(options: RenderPanelActionOptions): ReactNode {\n const {\n id,\n defaultProps,\n fiber,\n state,\n renderAction,\n t,\n buttonStyle = styles.actionButton,\n } = options;\n\n const customAction = renderAction?.({\n id,\n defaultProps,\n fiber,\n state,\n t,\n });\n\n if (customAction !== undefined) {\n return customAction;\n }\n\n const loadingText = defaultProps.loadingLabel ?? t('actions.loading.default', 'Processing...');\n\n return (\n <button\n type=\"button\"\n style={withDisabledStyle(buttonStyle, defaultProps.disabled)}\n disabled={defaultProps.disabled}\n onClick={() => {\n void defaultProps.onTrigger();\n }}\n >\n {defaultProps.loading ? loadingText : defaultProps.label}\n </button>\n );\n}\n","import type {\n CellDep,\n FiberBrowserNode,\n FiberWasmFactory,\n GraphChannelsResult,\n GraphNodesResult,\n HexString,\n ListPeersResult,\n NodeInfoResult,\n Script,\n} from '@fiber-pay/sdk/browser';\nimport type { CSSProperties, ReactNode } from 'react';\nimport type { ConnectButtonConnectedDropdownContext, ConnectStrategy } from '../connect-button.js';\nimport type { UseFiberNodeOptions, UseFiberNodeResult } from '../use-fiber-node.js';\nimport type { FiberNodeButtonPanelState } from './use-panel-state.js';\n\nexport const ONE_CKB_SHANNONS = '0x5f5e100';\n\nexport type ChannelFilter = 'active' | 'pending' | 'closed' | 'all';\nexport type PanelTab = string;\nexport type DefaultPanelTab = 'workbench' | 'channels' | 'diagnostics';\nexport type FiberNodeButtonTabId = PanelTab;\nexport type GraphChannelInfo = GraphChannelsResult['channels'][number];\nexport type GraphNodeInfo = GraphNodesResult['nodes'][number];\nexport type PeerInfo = ListPeersResult['peers'][number];\nexport type FiberNodeButtonI18n = (\n key: string,\n fallback: string,\n vars?: Record<string, string | number>,\n) => string;\n\nexport type FiberNodeButtonActionId =\n | 'open-channel'\n | 'create-invoice'\n | 'pay-invoice'\n | 'close-channel'\n | 'force-close-channel';\n\nexport interface FiberNodeButtonActionDefaultPropsBase {\n label: string;\n loadingLabel?: string;\n disabled: boolean;\n loading?: boolean;\n onTrigger: () => void | Promise<void>;\n}\n\nexport interface FiberNodeButtonOpenChannelActionDefaultProps\n extends FiberNodeButtonActionDefaultPropsBase {\n id: 'open-channel';\n}\n\nexport interface FiberNodeButtonCreateInvoiceActionDefaultProps\n extends FiberNodeButtonActionDefaultPropsBase {\n id: 'create-invoice';\n}\n\nexport interface FiberNodeButtonPayInvoiceActionDefaultProps\n extends FiberNodeButtonActionDefaultPropsBase {\n id: 'pay-invoice';\n}\n\nexport interface FiberNodeButtonCloseChannelActionDefaultProps\n extends FiberNodeButtonActionDefaultPropsBase {\n id: 'close-channel';\n channelId?: string;\n}\n\nexport interface FiberNodeButtonForceCloseChannelActionDefaultProps\n extends FiberNodeButtonActionDefaultPropsBase {\n id: 'force-close-channel';\n channelId?: string;\n}\n\nexport type FiberNodeButtonActionDefaultProps =\n | FiberNodeButtonOpenChannelActionDefaultProps\n | FiberNodeButtonCreateInvoiceActionDefaultProps\n | FiberNodeButtonPayInvoiceActionDefaultProps\n | FiberNodeButtonCloseChannelActionDefaultProps\n | FiberNodeButtonForceCloseChannelActionDefaultProps;\n\nexport interface FiberNodeButtonTabActions {\n openChannel: () => Promise<void>;\n createInvoice: () => Promise<void>;\n payInvoice: () => Promise<void>;\n closeChannel: (channelId: string) => Promise<void>;\n forceCloseChannel: (channelId: string) => Promise<void>;\n}\n\nexport interface FiberNodeButtonTabContext {\n fiber: UseFiberNodeResult;\n state: FiberNodeButtonPanelState;\n externalFundingEnabled: boolean;\n t: FiberNodeButtonI18n;\n actions: FiberNodeButtonTabActions;\n}\n\nexport interface FiberNodeButtonTabConfig {\n id: FiberNodeButtonTabId;\n label?: string | ((t: FiberNodeButtonI18n) => string);\n hidden?: boolean;\n render?: (context: FiberNodeButtonTabContext) => ReactNode;\n}\n\nexport interface FiberNodeButtonRenderActionContext {\n id: FiberNodeButtonActionId;\n defaultProps: FiberNodeButtonActionDefaultProps;\n fiber: UseFiberNodeResult;\n state: FiberNodeButtonPanelState;\n t: FiberNodeButtonI18n;\n}\n\nexport type FiberNodeButtonRenderAction = (\n context: FiberNodeButtonRenderActionContext,\n) => ReactNode | undefined;\n\nexport interface FiberNodeButtonExternalFundingResolved {\n signFundingTx: (txForSigner: unknown) => Promise<unknown>;\n shutdownScript?: Script;\n fundingLockScript?: Script;\n fundingLockScriptCellDeps?: CellDep[];\n ckbRpcUrl?: string;\n}\n\nexport interface FiberNodeButtonExternalFundingResolverContext {\n node: FiberBrowserNode;\n pubkey: HexString;\n fundingAmountCkb: string;\n}\n\nexport interface FiberNodeButtonExternalFundingConfig {\n enabled: boolean;\n resolve: (\n context: FiberNodeButtonExternalFundingResolverContext,\n ) => Promise<FiberNodeButtonExternalFundingResolved>;\n}\n\nexport interface FiberNodeButtonConnectorSectionContext {\n fiber: UseFiberNodeResult;\n externalFundingEnabled: boolean;\n isOpeningChannel: boolean;\n}\n\nexport interface FiberNodeButtonProps {\n network?: 'testnet' | 'mainnet';\n fiber?: UseFiberNodeResult;\n strategy?: ConnectStrategy;\n externalWallet?: boolean;\n password?: string;\n walletId?: string;\n passkeyUsername?: string;\n wasmFactory?: FiberWasmFactory;\n nodeConfig?: UseFiberNodeOptions['nodeConfig'];\n className?: string;\n style?: CSSProperties;\n dropdownStyle?: CSSProperties;\n onConnect?: (node: FiberBrowserNode, nodeInfo: NodeInfoResult) => void;\n onDisconnect?: () => void;\n onError?: (error: string) => void;\n onLog?: (message: string) => void;\n initialPeerPubkey?: string;\n initialPeerAddress?: string;\n initialFundingAmountCkb?: string;\n externalFunding?: FiberNodeButtonExternalFundingConfig;\n renderConnectorSection?: (context: FiberNodeButtonConnectorSectionContext) => ReactNode;\n tabs?: ReadonlyArray<FiberNodeButtonTabConfig>;\n renderTabContent?: (\n tabId: FiberNodeButtonTabId,\n context: FiberNodeButtonTabContext,\n ) => ReactNode | undefined;\n renderAction?: FiberNodeButtonRenderAction;\n t?: FiberNodeButtonI18n;\n}\n\nexport interface FiberNodeButtonPanelProps {\n dropdownContext: ConnectButtonConnectedDropdownContext;\n network: 'testnet' | 'mainnet';\n fiber: UseFiberNodeResult;\n onLog?: (message: string) => void;\n onError?: (error: string) => void;\n initialPeerPubkey: string;\n initialPeerAddress: string;\n initialFundingAmountCkb: string;\n externalFunding?: FiberNodeButtonExternalFundingConfig;\n renderConnectorSection?: (context: FiberNodeButtonConnectorSectionContext) => ReactNode;\n tabs?: ReadonlyArray<FiberNodeButtonTabConfig>;\n renderTabContent?: (\n tabId: FiberNodeButtonTabId,\n context: FiberNodeButtonTabContext,\n ) => ReactNode | undefined;\n renderAction?: FiberNodeButtonRenderAction;\n t?: FiberNodeButtonI18n;\n}\n\nexport const TAB_ITEMS: ReadonlyArray<{ id: DefaultPanelTab; label: string }> = [\n { id: 'workbench', label: 'Workbench' },\n { id: 'channels', label: 'Channels' },\n { id: 'diagnostics', label: 'Diagnostics' },\n];\n\nexport const DEFAULT_TAB_IDS: ReadonlyArray<DefaultPanelTab> = [\n 'workbench',\n 'channels',\n 'diagnostics',\n];\n\nexport const FILTER_ITEMS: ReadonlyArray<ChannelFilter> = ['active', 'pending', 'closed', 'all'];\n","import type { UseFiberNodeResult } from '../use-fiber-node.js';\nimport { renderPanelAction } from './render-action.js';\nimport { styles } from './styles.js';\nimport {\n FILTER_ITEMS,\n type FiberNodeButtonActionDefaultProps,\n type FiberNodeButtonRenderAction,\n type FiberNodeButtonTabContext,\n} from './types.js';\nimport type { FiberNodeButtonPanelState } from './use-panel-state.js';\nimport { formatChannelBalance, shorten, withDisabledStyle } from './utils.js';\n\nexport interface ChannelsTabProps {\n state: FiberNodeButtonPanelState;\n fiber: UseFiberNodeResult;\n onLog?: (message: string) => void;\n renderAction?: FiberNodeButtonRenderAction;\n t: FiberNodeButtonTabContext['t'];\n}\n\nexport function ChannelsTab({ state, fiber, onLog, renderAction, t }: ChannelsTabProps) {\n const {\n isRefreshingChannels,\n refreshChannels,\n channelCounts,\n channelFilter,\n setChannelFilter,\n visibleChannels,\n selectedChannelId,\n setSelectedChannelId,\n setForceCloseConfirmOpen,\n selectedChannel,\n selectedCanClose,\n selectedIsClosing,\n selectedPending,\n closeChannel,\n } = state;\n\n return (\n <>\n <section style={styles.section}>\n <div style={styles.rowBetween}>\n <h4 style={styles.sectionTitle}>{t('channels.summary.title', 'Channel Summary')}</h4>\n <button\n type=\"button\"\n style={withDisabledStyle(styles.actionButton, isRefreshingChannels)}\n disabled={isRefreshingChannels}\n onClick={() => {\n void refreshChannels();\n }}\n >\n {isRefreshingChannels\n ? t('channels.summary.refresh.loading', 'Refreshing...')\n : t('channels.summary.refresh', 'Refresh')}\n </button>\n </div>\n\n <p style={styles.summaryInline}>\n {t('channels.summary.active', 'Active')} {channelCounts.active} |{' '}\n {t('channels.summary.pending', 'Pending')} {channelCounts.pending} |{' '}\n {t('channels.summary.closed', 'Closed')} {channelCounts.closed} |{' '}\n {t('channels.summary.total', 'Total')} {channelCounts.all}\n </p>\n\n <div style={styles.filterBar}>\n {FILTER_ITEMS.map((filter) => (\n <button\n key={filter}\n type=\"button\"\n style={channelFilter === filter ? styles.primaryButton : styles.actionButton}\n onClick={() => setChannelFilter(filter)}\n >\n {filter === 'all'\n ? `${t('channels.filter.all', 'All')} (${channelCounts.all})`\n : `${filter} (${channelCounts[filter]})`}\n </button>\n ))}\n </div>\n\n <div style={styles.list}>\n {visibleChannels.length === 0 ? (\n <p style={styles.compactText}>\n {t('channels.list.empty', 'No channels found for this filter.')}\n </p>\n ) : (\n visibleChannels.map((channel) => {\n const selected = channel.channel_id === selectedChannelId;\n\n return (\n <button\n key={channel.channel_id}\n type=\"button\"\n style={{\n ...styles.compactChannelRow,\n ...(selected ? styles.compactChannelRowActive : {}),\n }}\n onClick={() => {\n setSelectedChannelId(channel.channel_id);\n setForceCloseConfirmOpen(false);\n }}\n >\n <span style={styles.srOnly}>\n {selected\n ? t('channels.list.selected', 'Selected channel')\n : t('channels.list.select', 'Select channel')}\n </span>\n <span style={styles.compactChannelTop}>\n <span style={styles.inlineCode}>\n {t('channels.list.id', 'ID')}: {shorten(channel.channel_id, 12, 8)}\n </span>\n <span style={styles.badge}>{channel.state.state_name}</span>\n </span>\n <span style={styles.compactText}>\n {t('channels.list.peer', 'Peer')}: {shorten(channel.pubkey, 16, 10)}\n </span>\n <span style={styles.compactText}>\n L {formatChannelBalance(channel.local_balance)} / R{' '}\n {formatChannelBalance(channel.remote_balance)} CKB\n </span>\n </button>\n );\n })\n )}\n </div>\n </section>\n\n {selectedChannel ? (\n <section style={styles.detailPanel}>\n <div style={styles.rowBetween}>\n <h4 style={styles.sectionTitle}>{t('channels.details.title', 'Channel Details')}</h4>\n <span style={styles.badge}>{selectedChannel.state.state_name}</span>\n </div>\n\n <p style={styles.inlineCode}>\n {t('channels.details.channelId', 'Channel ID')}: {selectedChannel.channel_id}\n </p>\n <p style={styles.inlineCode}>\n {t('channels.details.peer', 'Peer')}: {selectedChannel.pubkey}\n </p>\n\n <div style={styles.row}>\n <span style={styles.badge}>\n {t('channels.details.local', 'Local')}{' '}\n {formatChannelBalance(selectedChannel.local_balance)} CKB\n </span>\n <span style={styles.badge}>\n {t('channels.details.remote', 'Remote')}{' '}\n {formatChannelBalance(selectedChannel.remote_balance)} CKB\n </span>\n <span\n style={styles.badge}\n title=\"Pending TLCs are in-flight payment locks associated with this channel.\"\n >\n {t('channels.details.tlcs', 'TLCs')} {selectedChannel.pending_tlcs.length}\n </span>\n </div>\n\n {selectedChannel.failure_detail ? (\n <p style={styles.compactText}>\n {t('channels.details.failure', 'Failure')}: {selectedChannel.failure_detail}\n </p>\n ) : null}\n\n {selectedChannel.shutdown_transaction_hash ? (\n <p style={styles.inlineCode}>\n {t('channels.details.shutdownTx', 'Shutdown TX')}:{' '}\n {selectedChannel.shutdown_transaction_hash}\n </p>\n ) : null}\n\n <div style={{ ...styles.row, justifyContent: 'flex-end' }}>\n {renderPanelAction({\n id: 'close-channel',\n fiber,\n state,\n renderAction,\n t,\n defaultProps: {\n id: 'close-channel',\n channelId: selectedChannel.channel_id,\n label: selectedPending\n ? t('actions.abandonPending', 'Abandon Pending')\n : t('actions.closeChannel', 'Close Channel'),\n loadingLabel: t('actions.closeChannel.loading', 'Closing...'),\n disabled: !selectedCanClose || selectedIsClosing,\n loading: selectedIsClosing,\n onTrigger: async () => {\n await closeChannel(selectedChannel.channel_id, false);\n },\n } satisfies FiberNodeButtonActionDefaultProps,\n })}\n\n {renderPanelAction({\n id: 'force-close-channel',\n fiber,\n state,\n renderAction,\n t,\n buttonStyle: styles.dangerButton,\n defaultProps: {\n id: 'force-close-channel',\n channelId: selectedChannel.channel_id,\n label: t('actions.forceClose', 'Force Close'),\n disabled: !selectedCanClose || selectedPending || selectedIsClosing,\n onTrigger: () => {\n setForceCloseConfirmOpen(true);\n onLog?.('fiber_channel_force_close_confirm_opened');\n },\n } satisfies FiberNodeButtonActionDefaultProps,\n })}\n </div>\n </section>\n ) : null}\n </>\n );\n}\n","import { styles } from './styles.js';\nimport type { FiberNodeButtonTabContext } from './types.js';\nimport type { FiberNodeButtonPanelState } from './use-panel-state.js';\nimport { formatChannelBalance, shorten, withDisabledStyle } from './utils.js';\n\nexport interface DiagnosticsTabProps {\n state: FiberNodeButtonPanelState;\n t: FiberNodeButtonTabContext['t'];\n}\n\nexport function DiagnosticsTab({ state, t }: DiagnosticsTabProps) {\n const {\n isRefreshingPeers,\n refreshConnectedPeers,\n connectedPeers,\n setPeerPubkey,\n switchTab,\n peerAddress,\n setPeerAddress,\n isConnectingPeer,\n connectPeerByAddress,\n isRefreshingGraph,\n refreshDiagnostics,\n refreshGraph,\n graphNodes,\n graphChannels,\n channelOpenFlow,\n } = state;\n\n return (\n <>\n <section style={styles.section}>\n <div style={styles.rowBetween}>\n <h4 style={styles.sectionTitle}>{t('diagnostics.peers.title', 'Connected Peers')}</h4>\n <button\n type=\"button\"\n style={withDisabledStyle(styles.actionButton, isRefreshingPeers)}\n disabled={isRefreshingPeers}\n onClick={() => {\n void refreshConnectedPeers();\n }}\n >\n {isRefreshingPeers\n ? t('diagnostics.peers.refresh.loading', 'Refreshing...')\n : t('diagnostics.peers.refresh', 'Refresh Peers')}\n </button>\n </div>\n\n <p style={styles.compactText}>\n {t('diagnostics.peers.count', 'Peers')}: {connectedPeers.length}\n </p>\n\n <div style={{ ...styles.list, maxHeight: '190px' }}>\n {connectedPeers.length === 0 ? (\n <p style={styles.compactText}>{t('diagnostics.peers.empty', 'No connected peers.')}</p>\n ) : (\n connectedPeers.map((peer) => (\n <article key={peer.pubkey} style={styles.compactChannelRow}>\n <p style={styles.inlineCode}>{shorten(peer.pubkey, 18, 12)}</p>\n <details>\n <summary style={{ ...styles.compactText, cursor: 'pointer' }}>\n {t('diagnostics.peers.address', 'Address')}\n </summary>\n <p style={styles.inlineCode}>{peer.address}</p>\n </details>\n <div style={styles.row}>\n <button\n type=\"button\"\n style={styles.ghostButton}\n onClick={() => {\n setPeerPubkey(peer.pubkey);\n switchTab('workbench');\n }}\n >\n {t('diagnostics.peers.useForOpenChannel', 'Use for Open Channel')}\n </button>\n </div>\n </article>\n ))\n )}\n </div>\n\n <label style={styles.fieldLabel}>\n {t('diagnostics.peers.connectPeerAddress', 'Connect Peer Address')}\n <input\n style={styles.input}\n value={peerAddress}\n onChange={(event) => setPeerAddress(event.target.value)}\n placeholder=\"/dns4/.../wss/p2p/...\"\n />\n </label>\n\n <div style={styles.rowBetween}>\n <button\n type=\"button\"\n style={withDisabledStyle(styles.primaryButton, isConnectingPeer || !peerAddress.trim())}\n disabled={isConnectingPeer || !peerAddress.trim()}\n onClick={() => {\n void connectPeerByAddress();\n }}\n >\n {isConnectingPeer\n ? t('diagnostics.peers.connect.loading', 'Connecting...')\n : t('diagnostics.peers.connect', 'Connect Peer')}\n </button>\n\n <button\n type=\"button\"\n style={withDisabledStyle(styles.actionButton, isRefreshingPeers || isRefreshingGraph)}\n disabled={isRefreshingPeers || isRefreshingGraph}\n onClick={() => {\n void refreshDiagnostics();\n }}\n >\n {isRefreshingPeers || isRefreshingGraph\n ? t('diagnostics.peers.refreshAll.loading', 'Refreshing...')\n : t('diagnostics.peers.refreshAll', 'Refresh All')}\n </button>\n </div>\n </section>\n\n <section style={styles.section}>\n <div style={styles.rowBetween}>\n <h4 style={styles.sectionTitle}>{t('diagnostics.graph.title', 'Graph Snapshot')}</h4>\n <button\n type=\"button\"\n style={withDisabledStyle(styles.actionButton, isRefreshingGraph)}\n disabled={isRefreshingGraph}\n onClick={() => {\n void refreshGraph();\n }}\n >\n {isRefreshingGraph\n ? t('diagnostics.graph.refresh.loading', 'Refreshing...')\n : t('diagnostics.graph.refresh', 'Refresh Graph')}\n </button>\n </div>\n\n <p style={styles.compactText}>\n {t('diagnostics.graph.showing', 'showing')} {Math.min(graphNodes.length, 3)}{' '}\n {t('diagnostics.graph.of', 'of')} {graphNodes.length}{' '}\n {t('diagnostics.graph.nodes', 'nodes')}, {Math.min(graphChannels.length, 2)}{' '}\n {t('diagnostics.graph.of', 'of')} {graphChannels.length}{' '}\n {t('diagnostics.graph.channels', 'channels')}.\n </p>\n\n {graphNodes.slice(0, 3).map((node) => (\n <p key={node.pubkey} style={styles.inlineCode}>\n Node: {node.node_name || shorten(node.pubkey, 18, 10)}\n </p>\n ))}\n\n {graphChannels.slice(0, 2).map((channel) => (\n <p\n key={`${channel.node1}-${channel.node2}-${channel.channel_outpoint.tx_hash}`}\n style={styles.inlineCode}\n >\n {shorten(channel.node1, 10, 6)} to {shorten(channel.node2, 10, 6)};{' '}\n {formatChannelBalance(channel.capacity)} CKB\n </p>\n ))}\n\n <details>\n <summary style={{ ...styles.compactText, cursor: 'pointer' }}>\n {t('diagnostics.graph.rawSnapshot', 'Raw graph snapshot')}\n </summary>\n <pre\n style={{\n ...styles.inlineCode,\n marginTop: '0.45rem',\n maxHeight: '160px',\n overflow: 'auto',\n background: '#f1f5f9',\n borderRadius: '0.45rem',\n padding: '0.45rem',\n }}\n >\n {JSON.stringify(\n {\n nodes: graphNodes,\n channels: graphChannels,\n },\n null,\n 2,\n )}\n </pre>\n </details>\n </section>\n\n {channelOpenFlow.diagnostic ? (\n <div style={styles.notice}>{channelOpenFlow.diagnostic}</div>\n ) : null}\n </>\n );\n}\n","import type { FiberNodeButtonI18n } from './types.js';\n\nfunction applyVariables(template: string, vars?: Record<string, string | number>): string {\n if (!vars) {\n return template;\n }\n\n return template.replace(/\\{(\\w+)\\}/g, (full, key: string) => {\n const value = vars[key];\n return value === undefined ? full : String(value);\n });\n}\n\nexport const defaultFiberNodeButtonI18n: FiberNodeButtonI18n = (_key, fallback, vars) =>\n applyVariables(fallback, vars);\n","import type {\n AbandonChannelParams,\n Channel,\n GetPaymentResult,\n HexString,\n ShutdownChannelParams,\n} from '@fiber-pay/sdk/browser';\nimport { ChannelState } from '@fiber-pay/sdk/browser';\nimport {\n type Dispatch,\n type SetStateAction,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { type UseChannelOpenFlowResult, useChannelOpenFlow } from '../use-channel-open-flow.js';\nimport { useFiberPayment } from '../use-fiber-payment.js';\nimport {\n type ChannelFilter,\n type FiberNodeButtonConnectorSectionContext,\n type FiberNodeButtonPanelProps,\n type GraphChannelInfo,\n type GraphNodeInfo,\n ONE_CKB_SHANNONS,\n type PanelTab,\n type PeerInfo,\n} from './types.js';\nimport {\n getChannelFilterState,\n isPendingChannelState,\n shorten,\n summarizeError,\n toHexPrefixed,\n} from './utils.js';\n\nexport interface PanelStatusNotice {\n tone: 'info' | 'success';\n text: string;\n}\n\nexport interface PanelChannelCounts {\n active: number;\n pending: number;\n closed: number;\n all: number;\n}\n\nexport interface FiberNodeButtonPanelState {\n activeTab: PanelTab;\n switchTab: (next: PanelTab) => void;\n tabPanelId: string;\n peerPubkey: string;\n setPeerPubkey: Dispatch<SetStateAction<string>>;\n peerAddress: string;\n setPeerAddress: Dispatch<SetStateAction<string>>;\n fundingAmountCkb: string;\n setFundingAmountCkb: Dispatch<SetStateAction<string>>;\n peerListId: string;\n connectedPeers: PeerInfo[];\n isRefreshingPeers: boolean;\n isConnectingPeer: boolean;\n refreshConnectedPeers: () => Promise<void>;\n connectPeerByAddress: () => Promise<void>;\n graphNodes: GraphNodeInfo[];\n graphChannels: GraphChannelInfo[];\n isRefreshingGraph: boolean;\n refreshGraph: () => Promise<void>;\n channels: Channel[];\n channelFilter: ChannelFilter;\n setChannelFilter: Dispatch<SetStateAction<ChannelFilter>>;\n isRefreshingChannels: boolean;\n refreshChannels: () => Promise<void>;\n closeChannel: (channelId: string, force?: boolean) => Promise<void>;\n selectedChannelId: string | null;\n setSelectedChannelId: Dispatch<SetStateAction<string | null>>;\n selectedChannel: Channel | null;\n selectedPending: boolean;\n selectedCanClose: boolean;\n selectedIsClosing: boolean;\n forceCloseConfirmOpen: boolean;\n setForceCloseConfirmOpen: Dispatch<SetStateAction<boolean>>;\n channelCounts: PanelChannelCounts;\n visibleChannels: Channel[];\n activeChannelCount: number;\n invoiceInput: string;\n setInvoiceInput: Dispatch<SetStateAction<string>>;\n createdInvoice: string;\n isCreatingInvoice: boolean;\n createInvoice: () => Promise<void>;\n submitPayment: () => Promise<void>;\n isPaying: boolean;\n paymentResult: GetPaymentResult | null;\n channelOpenFlow: UseChannelOpenFlowResult;\n openChannel: () => Promise<void>;\n latestError: string | null;\n statusNotice: PanelStatusNotice | null;\n refreshDiagnostics: () => Promise<void>;\n isNodeReady: boolean;\n connectorContext: FiberNodeButtonConnectorSectionContext;\n}\n\nexport function useFiberNodeButtonPanelState(\n props: FiberNodeButtonPanelProps,\n): FiberNodeButtonPanelState {\n const {\n network,\n fiber,\n onLog,\n onError,\n initialPeerPubkey,\n initialPeerAddress,\n initialFundingAmountCkb,\n externalFunding,\n } = props;\n\n const [activeTab, setActiveTab] = useState<PanelTab>('workbench');\n\n const [peerPubkey, setPeerPubkey] = useState(initialPeerPubkey);\n const [peerAddress, setPeerAddress] = useState(initialPeerAddress);\n const [fundingAmountCkb, setFundingAmountCkb] = useState(initialFundingAmountCkb);\n\n const [connectedPeers, setConnectedPeers] = useState<PeerInfo[]>([]);\n const [isRefreshingPeers, setIsRefreshingPeers] = useState(false);\n const [isConnectingPeer, setIsConnectingPeer] = useState(false);\n\n const [graphNodes, setGraphNodes] = useState<GraphNodeInfo[]>([]);\n const [graphChannels, setGraphChannels] = useState<GraphChannelInfo[]>([]);\n const [isRefreshingGraph, setIsRefreshingGraph] = useState(false);\n\n const [channels, setChannels] = useState<Channel[]>([]);\n const [channelFilter, setChannelFilter] = useState<ChannelFilter>('active');\n const [isRefreshingChannels, setIsRefreshingChannels] = useState(false);\n const [closingChannelId, setClosingChannelId] = useState<string | null>(null);\n const [selectedChannelId, setSelectedChannelId] = useState<string | null>(null);\n const [forceCloseConfirmOpen, setForceCloseConfirmOpen] = useState(false);\n\n const [invoiceInput, setInvoiceInput] = useState('');\n const [createdInvoice, setCreatedInvoice] = useState('');\n const [isCreatingInvoice, setIsCreatingInvoice] = useState(false);\n\n const [latestError, setLatestError] = useState<string | null>(null);\n const [statusNotice, setStatusNotice] = useState<PanelStatusNotice | null>(null);\n\n const statusTimerRef = useRef<number | null>(null);\n const mountedRef = useRef(true);\n const peerListId = useId();\n const tabPanelId = useId();\n\n const channelOpenFlow = useChannelOpenFlow({\n node: fiber.node,\n onLog,\n });\n\n const { payInvoice, isPaying, paymentResult, error: paymentError } = useFiberPayment(fiber.node);\n\n const isNodeReady = fiber.isRunning && !!fiber.node;\n\n useEffect(() => {\n return () => {\n mountedRef.current = false;\n if (statusTimerRef.current !== null) {\n window.clearTimeout(statusTimerRef.current);\n }\n };\n }, []);\n\n const flashStatus = useCallback((text: string, tone: 'info' | 'success' = 'info') => {\n setStatusNotice({ tone, text });\n if (statusTimerRef.current !== null) {\n window.clearTimeout(statusTimerRef.current);\n }\n statusTimerRef.current = window.setTimeout(() => {\n setStatusNotice(null);\n statusTimerRef.current = null;\n }, 3200);\n }, []);\n\n const reportError = useCallback(\n (message: string) => {\n setLatestError(message);\n onError?.(message);\n onLog?.(`fiber_panel_error_shown: ${summarizeError(message, 120)}`);\n },\n [onError, onLog],\n );\n\n const refreshConnectedPeers = useCallback(async () => {\n if (!fiber.node) {\n if (mountedRef.current) {\n setConnectedPeers([]);\n }\n return;\n }\n\n if (!mountedRef.current) {\n return;\n }\n\n setIsRefreshingPeers(true);\n\n try {\n const peers = await fiber.node.listPeers();\n if (!mountedRef.current) {\n return;\n }\n setConnectedPeers(peers.peers);\n setPeerPubkey((prev) => (prev.trim() ? prev : (peers.peers[0]?.pubkey ?? prev)));\n onLog?.(`Loaded connected peers: ${peers.peers.length}.`);\n } catch (error) {\n if (!mountedRef.current) {\n return;\n }\n const message = error instanceof Error ? error.message : String(error);\n reportError(message);\n onLog?.(`Refresh peers failed: ${message}`);\n } finally {\n if (mountedRef.current) {\n setIsRefreshingPeers(false);\n }\n }\n }, [fiber.node, onLog, reportError]);\n\n const refreshGraph = useCallback(async () => {\n if (!fiber.node) {\n if (mountedRef.current) {\n setGraphNodes([]);\n setGraphChannels([]);\n }\n return;\n }\n\n if (!mountedRef.current) {\n return;\n }\n\n setIsRefreshingGraph(true);\n\n try {\n const [nodesResult, channelsResult] = await Promise.all([\n fiber.node.graphNodes({ limit: '0x8' }),\n fiber.node.graphChannels({ limit: '0x8' }),\n ]);\n if (!mountedRef.current) {\n return;\n }\n setGraphNodes(nodesResult.nodes);\n setGraphChannels(channelsResult.channels);\n onLog?.(\n `Loaded graph: ${nodesResult.nodes.length} nodes, ${channelsResult.channels.length} channels.`,\n );\n } catch (error) {\n if (!mountedRef.current) {\n return;\n }\n const message = error instanceof Error ? error.message : String(error);\n reportError(message);\n onLog?.(`Refresh graph failed: ${message}`);\n } finally {\n if (mountedRef.current) {\n setIsRefreshingGraph(false);\n }\n }\n }, [fiber.node, onLog, reportError]);\n\n const refreshChannels = useCallback(async () => {\n if (!fiber.node) {\n if (mountedRef.current) {\n setChannels([]);\n }\n return;\n }\n\n if (!mountedRef.current) {\n return;\n }\n\n setIsRefreshingChannels(true);\n\n try {\n const result = await fiber.node.listChannels({ include_closed: true });\n if (!mountedRef.current) {\n return;\n }\n setChannels(result.channels);\n onLog?.(`Loaded channels: ${result.channels.length}.`);\n } catch (error) {\n if (!mountedRef.current) {\n return;\n }\n const message = error instanceof Error ? error.message : String(error);\n reportError(message);\n onLog?.(`Refresh channels failed: ${message}`);\n } finally {\n if (mountedRef.current) {\n setIsRefreshingChannels(false);\n }\n }\n }, [fiber.node, onLog, reportError]);\n\n const closeChannel = useCallback(\n async (channelId: string, force = false) => {\n if (!fiber.node) {\n reportError('Node is not connected.');\n return;\n }\n\n setClosingChannelId(channelId);\n\n try {\n const latest = await fiber.node.listChannels({ include_closed: true });\n const target = latest.channels.find((item) => item.channel_id === channelId);\n\n if (!target) {\n throw new Error(`Channel not found in latest snapshot: ${channelId}.`);\n }\n\n if (target.state.state_name === ChannelState.Closed) {\n setChannels(latest.channels);\n flashStatus('Channel is already closed.', 'info');\n onLog?.(`Channel already closed: ${channelId}`);\n return;\n }\n\n if (target.state.state_name === ChannelState.ShuttingDown) {\n setChannels(latest.channels);\n flashStatus('Channel is already shutting down.', 'info');\n onLog?.(`Channel is already shutting down: ${channelId}`);\n return;\n }\n\n if (isPendingChannelState(target.state.state_name)) {\n const params: AbandonChannelParams = {\n channel_id: channelId as HexString,\n };\n await fiber.node.abandonChannel(params);\n flashStatus('Pending channel abandoned.', 'success');\n onLog?.(`Pending channel abandoned: ${channelId}`);\n } else {\n const params: ShutdownChannelParams = {\n channel_id: channelId as HexString,\n force,\n };\n await fiber.node.shutdownChannel(params);\n flashStatus(force ? 'Force close requested.' : 'Close requested.', 'success');\n onLog?.(`${force ? 'Force close' : 'Close'} channel requested: ${channelId}`);\n }\n\n await refreshChannels();\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n reportError(message);\n } finally {\n setClosingChannelId(null);\n }\n },\n [fiber.node, flashStatus, onLog, refreshChannels, reportError],\n );\n\n const connectPeerByAddress = useCallback(async () => {\n if (!fiber.node) {\n reportError('Node is not connected.');\n return;\n }\n\n if (!peerAddress.trim()) {\n reportError('Peer address is empty.');\n return;\n }\n\n setIsConnectingPeer(true);\n\n try {\n await fiber.node.connectPeer({\n address: peerAddress.trim(),\n save: true,\n });\n flashStatus('Peer connected.', 'success');\n onLog?.('Peer connected from address input.');\n await refreshConnectedPeers();\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n reportError(message);\n onLog?.(`Connect peer failed: ${message}`);\n } finally {\n setIsConnectingPeer(false);\n }\n }, [fiber.node, flashStatus, onLog, peerAddress, refreshConnectedPeers, reportError]);\n\n const openChannel = useCallback(async () => {\n if (!fiber.node) {\n reportError('Node is not connected.');\n return;\n }\n\n if (!peerPubkey.trim()) {\n reportError('Target peer pubkey is empty.');\n return;\n }\n\n channelOpenFlow.reset();\n\n try {\n const pubkey = toHexPrefixed(peerPubkey);\n\n if (!externalFunding?.enabled) {\n const openResult = await channelOpenFlow.openChannel({\n pubkey,\n fundingAmountCkb,\n externalWallet: false,\n });\n if (!openResult) {\n return;\n }\n flashStatus('Open channel submitted.', 'success');\n onLog?.('fiber_panel_primary_action_clicked: open_channel');\n await refreshChannels();\n return;\n }\n\n const resolved = await externalFunding.resolve({\n node: fiber.node,\n pubkey,\n fundingAmountCkb,\n });\n\n const openResult = await channelOpenFlow.openChannel({\n pubkey,\n fundingAmountCkb,\n externalWallet: true,\n shutdownScript: resolved.shutdownScript,\n fundingLockScript: resolved.fundingLockScript,\n fundingLockScriptCellDeps: resolved.fundingLockScriptCellDeps,\n signFundingTx: resolved.signFundingTx,\n ckbRpcUrl: resolved.ckbRpcUrl,\n });\n if (!openResult) {\n return;\n }\n flashStatus('Open channel submitted.', 'success');\n onLog?.('fiber_panel_primary_action_clicked: open_channel');\n await refreshChannels();\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n reportError(message);\n onLog?.(`Open channel failed: ${message}`);\n }\n }, [\n channelOpenFlow,\n externalFunding,\n fiber.node,\n flashStatus,\n fundingAmountCkb,\n onLog,\n peerPubkey,\n refreshChannels,\n reportError,\n ]);\n\n const createInvoice = useCallback(async () => {\n if (!fiber.node) {\n reportError('Node is not connected.');\n return;\n }\n\n setIsCreatingInvoice(true);\n\n try {\n const created = await fiber.node.newInvoice({\n amount: ONE_CKB_SHANNONS,\n currency: network === 'mainnet' ? 'Fibb' : 'Fibt',\n description: 'FiberNodeButton invoice',\n });\n setCreatedInvoice(created.invoice_address);\n flashStatus('Invoice created.', 'success');\n onLog?.('fiber_panel_primary_action_clicked: create_invoice');\n onLog?.(`Invoice created: ${shorten(created.invoice_address, 20, 8)}`);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n reportError(message);\n } finally {\n setIsCreatingInvoice(false);\n }\n }, [fiber.node, flashStatus, network, onLog, reportError]);\n\n const submitPayment = useCallback(async () => {\n if (!invoiceInput.trim()) {\n reportError('Invoice is empty.');\n return;\n }\n\n onLog?.('fiber_panel_primary_action_clicked: pay_invoice');\n await payInvoice(invoiceInput);\n }, [invoiceInput, onLog, payInvoice, reportError]);\n\n useEffect(() => {\n if (!fiber.isRunning || !fiber.node) {\n setConnectedPeers([]);\n setGraphNodes([]);\n setGraphChannels([]);\n setChannels([]);\n setSelectedChannelId(null);\n return;\n }\n\n void refreshConnectedPeers();\n void refreshGraph();\n void refreshChannels();\n }, [fiber.isRunning, fiber.node, refreshChannels, refreshConnectedPeers, refreshGraph]);\n\n useEffect(() => {\n if (paymentError) {\n reportError(paymentError);\n }\n }, [paymentError, reportError]);\n\n useEffect(() => {\n if (channelOpenFlow.error) {\n reportError(channelOpenFlow.error);\n }\n }, [channelOpenFlow.error, reportError]);\n\n useEffect(() => {\n if (!paymentResult) {\n return;\n }\n\n flashStatus(`Payment ${paymentResult.status}.`, 'success');\n onLog?.(`Payment status: ${paymentResult.status}`);\n }, [flashStatus, onLog, paymentResult]);\n\n const channelCounts = useMemo(() => {\n const counts = { active: 0, pending: 0, closed: 0, all: channels.length };\n\n for (const channel of channels) {\n counts[getChannelFilterState(channel)] += 1;\n }\n\n return counts;\n }, [channels]);\n\n const visibleChannels = useMemo(\n () =>\n channelFilter === 'all'\n ? channels\n : channels.filter((channel) => getChannelFilterState(channel) === channelFilter),\n [channelFilter, channels],\n );\n\n const activeChannelCount = channelCounts.active;\n\n const selectedChannel = useMemo(\n () => channels.find((channel) => channel.channel_id === selectedChannelId) ?? null,\n [channels, selectedChannelId],\n );\n\n useEffect(() => {\n if (!selectedChannelId) {\n return;\n }\n if (!channels.some((channel) => channel.channel_id === selectedChannelId)) {\n setSelectedChannelId(null);\n setForceCloseConfirmOpen(false);\n }\n }, [channels, selectedChannelId]);\n\n useEffect(() => {\n const isSelectedVisible = selectedChannelId\n ? visibleChannels.some((channel) => channel.channel_id === selectedChannelId)\n : false;\n\n if (!isSelectedVisible) {\n setSelectedChannelId(visibleChannels[0]?.channel_id ?? null);\n setForceCloseConfirmOpen(false);\n }\n }, [selectedChannelId, visibleChannels]);\n\n const selectedState = selectedChannel?.state.state_name;\n const selectedPending = selectedChannel\n ? isPendingChannelState(selectedState as ChannelState)\n : false;\n const selectedCanClose =\n !!selectedChannel &&\n selectedState !== ChannelState.Closed &&\n selectedState !== ChannelState.ShuttingDown;\n const selectedIsClosing = !!selectedChannel && closingChannelId === selectedChannel.channel_id;\n\n const connectorContext: FiberNodeButtonConnectorSectionContext = useMemo(\n () => ({\n fiber,\n externalFundingEnabled: !!externalFunding?.enabled,\n isOpeningChannel: channelOpenFlow.isOpening,\n }),\n [channelOpenFlow.isOpening, externalFunding?.enabled, fiber],\n );\n\n const switchTab = useCallback(\n (next: PanelTab) => {\n setActiveTab(next);\n onLog?.(`fiber_panel_tab_switched: ${next}`);\n },\n [onLog],\n );\n\n const refreshDiagnostics = useCallback(async () => {\n await Promise.all([refreshConnectedPeers(), refreshGraph()]);\n flashStatus('Diagnostics refreshed.', 'info');\n }, [flashStatus, refreshConnectedPeers, refreshGraph]);\n\n return {\n // tab\n activeTab,\n switchTab,\n tabPanelId,\n // inputs\n peerPubkey,\n setPeerPubkey,\n peerAddress,\n setPeerAddress,\n fundingAmountCkb,\n setFundingAmountCkb,\n peerListId,\n // peers\n connectedPeers,\n isRefreshingPeers,\n isConnectingPeer,\n refreshConnectedPeers,\n connectPeerByAddress,\n // graph\n graphNodes,\n graphChannels,\n isRefreshingGraph,\n refreshGraph,\n // channels\n channels,\n channelFilter,\n setChannelFilter,\n isRefreshingChannels,\n refreshChannels,\n closeChannel,\n selectedChannelId,\n setSelectedChannelId,\n selectedChannel,\n selectedPending,\n selectedCanClose,\n selectedIsClosing,\n forceCloseConfirmOpen,\n setForceCloseConfirmOpen,\n channelCounts,\n visibleChannels,\n activeChannelCount,\n // payments\n invoiceInput,\n setInvoiceInput,\n createdInvoice,\n isCreatingInvoice,\n createInvoice,\n submitPayment,\n isPaying,\n paymentResult,\n // flow\n channelOpenFlow,\n openChannel,\n // notices\n latestError,\n statusNotice,\n // diagnostics aggregate\n refreshDiagnostics,\n // misc\n isNodeReady,\n connectorContext,\n };\n}\n","import {\n type CellDep,\n computeSuggestedFundingAmountCkb,\n diagnoseExternalFundingFailure,\n extractRequiredCapacityCkbFromFundingError,\n type HexString,\n type IFiberClient,\n type OpenChannelWithExternalFundingFlowResult,\n openChannelWithExternalFundingFlow,\n type Script,\n shouldDiagnoseFundingAbortError,\n} from '@fiber-pay/sdk/browser';\nimport { useCallback, useMemo, useState } from 'react';\n\nconst SHANNONS_PER_CKB = 100_000_000n;\n\nfunction toHexPrefixed(value: string): HexString {\n const trimmed = value.trim();\n if (!trimmed) {\n throw new Error('Hex value is empty.');\n }\n return (trimmed.startsWith('0x') ? trimmed : `0x${trimmed}`) as HexString;\n}\n\nfunction ckbToShannons(amountCkb: string): bigint {\n const normalized = amountCkb.trim();\n if (!/^\\d+(\\.\\d+)?$/.test(normalized)) {\n throw new Error('Funding amount must be a valid CKB number.');\n }\n\n const [wholePart, fracPart = ''] = normalized.split('.');\n if (fracPart.length > 8 && /[1-9]/.test(fracPart.slice(8))) {\n throw new Error('Funding amount supports up to 8 decimal places.');\n }\n\n const fracPadded = `${fracPart}00000000`.slice(0, 8);\n const shannons = BigInt(wholePart) * SHANNONS_PER_CKB + BigInt(fracPadded || '0');\n if (shannons <= 0n) {\n throw new Error('Funding amount must be greater than 0.');\n }\n return shannons;\n}\n\nexport interface ChannelOpenFlowParams {\n pubkey: string;\n fundingAmountCkb: string;\n externalWallet: boolean;\n shutdownScript?: Script;\n fundingLockScript?: Script;\n fundingLockScriptCellDeps?: CellDep[];\n signFundingTx?: (txForSigner: unknown) => Promise<unknown>;\n ckbRpcUrl?: string;\n}\n\nexport interface ChannelOpenFlowResult {\n mode: 'internal' | 'external';\n channelId: HexString;\n fundingTxHash?: HexString;\n unsignedFundingTx?: unknown;\n signedFundingTx?: Record<string, unknown>;\n}\n\nexport interface UseChannelOpenFlowOptions {\n node: IFiberClient | null;\n onLog?: (message: string) => void;\n}\n\nexport interface UseChannelOpenFlowResult {\n openChannel: (params: ChannelOpenFlowParams) => Promise<ChannelOpenFlowResult | null>;\n reset: () => void;\n isOpening: boolean;\n error: string | null;\n diagnostic: string | null;\n suggestedFundingAmountCkb: string | null;\n lastResult: ChannelOpenFlowResult | null;\n}\n\nfunction toHookResultFromExternal(\n result: OpenChannelWithExternalFundingFlowResult,\n): ChannelOpenFlowResult {\n return {\n mode: 'external',\n channelId: result.channelId,\n fundingTxHash: result.fundingTxHash,\n unsignedFundingTx: result.unsignedFundingTx,\n signedFundingTx: result.signedFundingTx,\n };\n}\n\nexport function useChannelOpenFlow(options: UseChannelOpenFlowOptions): UseChannelOpenFlowResult {\n const { node, onLog } = options;\n const [isOpening, setIsOpening] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [diagnostic, setDiagnostic] = useState<string | null>(null);\n const [suggestedFundingAmountCkb, setSuggestedFundingAmountCkb] = useState<string | null>(null);\n const [lastResult, setLastResult] = useState<ChannelOpenFlowResult | null>(null);\n\n const reset = useCallback(() => {\n setError(null);\n setDiagnostic(null);\n setSuggestedFundingAmountCkb(null);\n setLastResult(null);\n }, []);\n\n const openChannel = useCallback(\n async (params: ChannelOpenFlowParams): Promise<ChannelOpenFlowResult | null> => {\n if (!node) {\n setError('Node is not connected.');\n return null;\n }\n\n setIsOpening(true);\n setError(null);\n setDiagnostic(null);\n setSuggestedFundingAmountCkb(null);\n\n let requestedFundingShannons: bigint | undefined;\n let effectiveFundingLockScript: Script | undefined = params.fundingLockScript;\n\n try {\n requestedFundingShannons = ckbToShannons(params.fundingAmountCkb);\n const pubkey = toHexPrefixed(params.pubkey);\n\n if (!params.externalWallet) {\n const openResult = await node.openChannel({\n pubkey,\n funding_amount: `0x${requestedFundingShannons.toString(16)}` as HexString,\n });\n const result: ChannelOpenFlowResult = {\n mode: 'internal',\n channelId: openResult.temporary_channel_id,\n };\n setLastResult(result);\n onLog?.(`Internal channel open requested: ${openResult.temporary_channel_id}`);\n return result;\n }\n\n if (!params.signFundingTx) {\n throw new Error('Missing signFundingTx callback for external wallet funding flow.');\n }\n\n const nodeInfo = await node.nodeInfo();\n const defaultScript = nodeInfo.default_funding_lock_script;\n const shutdownScript = params.shutdownScript ?? defaultScript;\n effectiveFundingLockScript = params.fundingLockScript ?? defaultScript;\n\n const flowResult = await openChannelWithExternalFundingFlow({\n node,\n params: {\n pubkey,\n funding_amount: `0x${requestedFundingShannons.toString(16)}` as HexString,\n shutdown_script: shutdownScript,\n funding_lock_script: effectiveFundingLockScript,\n funding_lock_script_cell_deps: params.fundingLockScriptCellDeps,\n },\n signFundingTx: params.signFundingTx,\n });\n\n const result = toHookResultFromExternal(flowResult);\n setLastResult(result);\n onLog?.(\n `External funding completed: channel=${flowResult.channelId}, tx=${flowResult.fundingTxHash}`,\n );\n return result;\n } catch (unknownError) {\n const message = unknownError instanceof Error ? unknownError.message : String(unknownError);\n let displayMessage = message;\n\n const requiredCapacity = extractRequiredCapacityCkbFromFundingError(message);\n if (requiredCapacity) {\n try {\n const suggested = computeSuggestedFundingAmountCkb(\n params.fundingAmountCkb,\n requiredCapacity,\n );\n if (suggested) {\n setSuggestedFundingAmountCkb(suggested);\n displayMessage = `Insufficient capacity: current amount ${params.fundingAmountCkb} CKB may not cover fee. Suggested amount: ${suggested} CKB. Original error: ${message}`;\n }\n } catch {\n // Preserve original flow error when suggestion calculation fails.\n }\n }\n\n setError(displayMessage);\n\n if (params.externalWallet) {\n const hasKnownAbortPattern = shouldDiagnoseFundingAbortError(message);\n if (!hasKnownAbortPattern) {\n onLog?.(\n 'External funding error did not match known abort patterns; running best-effort diagnostics.',\n );\n }\n\n const targetPubkey = (() => {\n try {\n return toHexPrefixed(params.pubkey);\n } catch {\n return undefined;\n }\n })();\n\n try {\n const diagnoseResult = await diagnoseExternalFundingFailure({\n node,\n rawError: message,\n targetPubkey,\n fundingLockScript: effectiveFundingLockScript,\n requestedFundingShannons,\n ckbRpcUrl: params.ckbRpcUrl,\n });\n\n if (diagnoseResult.summary) {\n setDiagnostic(diagnoseResult.summary);\n onLog?.(`External funding diagnostic: ${diagnoseResult.summary}`);\n } else {\n const fallbackDiagnostic =\n 'No additional channel diagnostics were available for this external funding error.';\n setDiagnostic(fallbackDiagnostic);\n onLog?.(fallbackDiagnostic);\n }\n } catch (diagnosticError) {\n const diagnosticMessage =\n diagnosticError instanceof Error ? diagnosticError.message : String(diagnosticError);\n const fallbackDiagnostic =\n 'External funding diagnostics failed; no additional diagnostic details are available.';\n setDiagnostic(fallbackDiagnostic);\n onLog?.(`External funding diagnostics failed: ${diagnosticMessage}`);\n }\n }\n\n onLog?.(`Channel open flow failed: ${message}`);\n return null;\n } finally {\n setIsOpening(false);\n }\n },\n [node, onLog],\n );\n\n return useMemo(\n () => ({\n openChannel,\n reset,\n isOpening,\n error,\n diagnostic,\n suggestedFundingAmountCkb,\n lastResult,\n }),\n [openChannel, reset, isOpening, error, diagnostic, suggestedFundingAmountCkb, lastResult],\n );\n}\n","import type {\n FiberBrowserNode,\n GetPaymentResult,\n ParseInvoiceResult,\n PaymentHash,\n SendPaymentResult,\n} from '@fiber-pay/sdk/browser';\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nexport interface UseFiberPaymentResult {\n parseInvoice: (invoice: string) => Promise<ParseInvoiceResult>;\n sendPayment: (invoice: string) => Promise<SendPaymentResult>;\n waitForPayment: (paymentHash: PaymentHash) => Promise<GetPaymentResult>;\n payInvoice: (invoice: string) => Promise<void>;\n isPaying: boolean;\n paymentResult: GetPaymentResult | null;\n error: string | null;\n}\n\nfunction asErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n\nexport function useFiberPayment(node: FiberBrowserNode | null): UseFiberPaymentResult {\n const [isPaying, setIsPaying] = useState(false);\n const [paymentResult, setPaymentResult] = useState<GetPaymentResult | null>(null);\n const [error, setError] = useState<string | null>(null);\n const isMountedRef = useRef(true);\n\n useEffect(\n () => () => {\n isMountedRef.current = false;\n },\n [],\n );\n\n const ensureNode = useCallback(() => {\n if (!node) {\n throw new Error('Node is not initialized');\n }\n\n return node;\n }, [node]);\n\n const parseInvoiceInternal = useCallback(\n async (invoice: string) => {\n const activeNode = ensureNode();\n return activeNode.parseInvoice({ invoice });\n },\n [ensureNode],\n );\n\n const sendPaymentInternal = useCallback(\n async (invoice: string) => {\n const activeNode = ensureNode();\n return activeNode.sendPayment({ invoice });\n },\n [ensureNode],\n );\n\n const waitForPaymentInternal = useCallback(\n async (paymentHash: PaymentHash) => {\n const activeNode = ensureNode();\n return activeNode.waitForPayment(paymentHash);\n },\n [ensureNode],\n );\n\n const parseInvoice = useCallback(\n async (invoice: string) => {\n if (isMountedRef.current) {\n setError(null);\n }\n\n try {\n return await parseInvoiceInternal(invoice);\n } catch (parseError) {\n if (isMountedRef.current) {\n setError(asErrorMessage(parseError));\n }\n throw parseError;\n }\n },\n [parseInvoiceInternal],\n );\n\n const sendPayment = useCallback(\n async (invoice: string) => {\n if (isMountedRef.current) {\n setIsPaying(true);\n setError(null);\n setPaymentResult(null);\n }\n\n try {\n return await sendPaymentInternal(invoice);\n } catch (sendError) {\n if (isMountedRef.current) {\n setError(asErrorMessage(sendError));\n }\n throw sendError;\n } finally {\n if (isMountedRef.current) {\n setIsPaying(false);\n }\n }\n },\n [sendPaymentInternal],\n );\n\n const waitForPayment = useCallback(\n async (paymentHash: PaymentHash) => {\n if (isMountedRef.current) {\n setIsPaying(true);\n setError(null);\n setPaymentResult(null);\n }\n\n try {\n const result = await waitForPaymentInternal(paymentHash);\n if (isMountedRef.current) {\n setPaymentResult(result);\n }\n return result;\n } catch (waitError) {\n if (isMountedRef.current) {\n setError(asErrorMessage(waitError));\n }\n throw waitError;\n } finally {\n if (isMountedRef.current) {\n setIsPaying(false);\n }\n }\n },\n [waitForPaymentInternal],\n );\n\n const payInvoice = useCallback(\n async (invoice: string) => {\n if (isMountedRef.current) {\n setIsPaying(true);\n setError(null);\n setPaymentResult(null);\n }\n\n try {\n const parsed = await parseInvoiceInternal(invoice);\n await sendPaymentInternal(invoice);\n\n const paymentHash = parsed.invoice.data.payment_hash;\n const result = await waitForPaymentInternal(paymentHash);\n\n if (result.status === 'Failed') {\n throw new Error(result.failed_error ?? 'Payment failed during routing/execution');\n }\n\n if (isMountedRef.current) {\n setPaymentResult(result);\n }\n } catch (payError) {\n if (isMountedRef.current) {\n setError(asErrorMessage(payError));\n }\n } finally {\n if (isMountedRef.current) {\n setIsPaying(false);\n }\n }\n },\n [parseInvoiceInternal, sendPaymentInternal, waitForPaymentInternal],\n );\n\n return {\n parseInvoice,\n sendPayment,\n waitForPayment,\n payInvoice,\n isPaying,\n paymentResult,\n error,\n };\n}\n","import { renderPanelAction } from './render-action.js';\nimport { styles } from './styles.js';\nimport type {\n FiberNodeButtonActionDefaultProps,\n FiberNodeButtonPanelProps,\n FiberNodeButtonRenderAction,\n FiberNodeButtonTabContext,\n} from './types.js';\nimport type { FiberNodeButtonPanelState } from './use-panel-state.js';\nimport { shorten } from './utils.js';\n\nexport interface WorkbenchTabProps {\n state: FiberNodeButtonPanelState;\n fiber: FiberNodeButtonPanelProps['fiber'];\n externalFunding: FiberNodeButtonPanelProps['externalFunding'];\n renderConnectorSection: FiberNodeButtonPanelProps['renderConnectorSection'];\n renderAction?: FiberNodeButtonRenderAction;\n t: FiberNodeButtonTabContext['t'];\n}\n\nexport function WorkbenchTab({\n state,\n fiber,\n externalFunding,\n renderConnectorSection,\n renderAction,\n t,\n}: WorkbenchTabProps) {\n const {\n isNodeReady,\n connectorContext,\n channelOpenFlow,\n peerListId,\n peerPubkey,\n setPeerPubkey,\n connectedPeers,\n fundingAmountCkb,\n setFundingAmountCkb,\n openChannel,\n isCreatingInvoice,\n createInvoice,\n createdInvoice,\n invoiceInput,\n setInvoiceInput,\n isPaying,\n submitPayment,\n paymentResult,\n } = state;\n\n return (\n <>\n <section style={styles.section}>\n <div style={styles.rowBetween}>\n <h4 style={styles.sectionTitle}>\n {t('workbench.connectionPrep.title', 'Connection Prep')}\n </h4>\n <span style={styles.badge}>\n {isNodeReady\n ? t('workbench.connectionPrep.connected', 'Connected')\n : t('workbench.connectionPrep.disconnected', 'Disconnected')}\n </span>\n </div>\n <p style={styles.compactText}>\n {t('workbench.connectionPrep.node', 'Node')}:{' '}\n {fiber.nodeInfo?.pubkey ? shorten(fiber.nodeInfo.pubkey, 18, 12) : t('meta.na', 'N/A')}\n </p>\n <p style={styles.compactText}>\n {t('workbench.connectionPrep.externalWallet', 'External wallet')}:{' '}\n {externalFunding?.enabled\n ? t('workbench.connectionPrep.enabled', 'Enabled')\n : t('workbench.connectionPrep.disabled', 'Disabled')}\n </p>\n\n {renderConnectorSection ? (\n <div style={{ borderTop: '1px solid #e2e8f0', paddingTop: '0.55rem' }}>\n {renderConnectorSection(connectorContext)}\n </div>\n ) : null}\n </section>\n\n <section style={styles.section}>\n <div style={styles.rowBetween}>\n <h4 style={styles.sectionTitle}>{t('workbench.openChannel.title', 'Open Channel')}</h4>\n {channelOpenFlow.lastResult ? (\n <span style={styles.badge}>\n {t('workbench.openChannel.recentSuccess', 'Recent Success')}\n </span>\n ) : null}\n </div>\n\n <label style={styles.fieldLabel}>\n {t('workbench.openChannel.targetPeerPubkey', 'Target Peer Pubkey')}\n <input\n style={styles.input}\n list={peerListId}\n value={peerPubkey}\n onChange={(event) => setPeerPubkey(event.target.value)}\n placeholder={connectedPeers[0]?.pubkey ?? '0x...'}\n />\n <datalist id={peerListId}>\n {connectedPeers.map((peer) => (\n <option key={peer.pubkey} value={peer.pubkey} />\n ))}\n </datalist>\n </label>\n\n <label style={styles.fieldLabel}>\n {t('workbench.openChannel.fundingAmount', 'Funding Amount (CKB)')}\n <input\n style={styles.input}\n value={fundingAmountCkb}\n onChange={(event) => setFundingAmountCkb(event.target.value)}\n placeholder=\"1000\"\n />\n </label>\n\n <div style={styles.row}>\n {renderPanelAction({\n id: 'open-channel',\n fiber,\n state,\n renderAction,\n t,\n buttonStyle: styles.primaryButton,\n defaultProps: {\n id: 'open-channel',\n label: t('actions.openChannel', 'Open Channel'),\n loadingLabel: t('actions.openChannel.loading', 'Opening...'),\n disabled: !isNodeReady || channelOpenFlow.isOpening || !peerPubkey.trim(),\n loading: channelOpenFlow.isOpening,\n onTrigger: openChannel,\n } satisfies FiberNodeButtonActionDefaultProps,\n })}\n </div>\n\n {channelOpenFlow.lastResult ? (\n <p style={styles.compactText}>\n {t('workbench.openChannel.lastChannel', 'Last channel')}:{' '}\n {shorten(channelOpenFlow.lastResult.channelId, 14, 8)}\n </p>\n ) : null}\n\n {channelOpenFlow.suggestedFundingAmountCkb ? (\n <p style={styles.compactText}>\n {t('workbench.openChannel.suggestedAmount', 'Suggested amount')}:{' '}\n {channelOpenFlow.suggestedFundingAmountCkb} CKB\n </p>\n ) : null}\n </section>\n\n <section style={styles.section}>\n <h4 style={styles.sectionTitle}>{t('workbench.payments.title', 'Payments')}</h4>\n\n <div style={styles.row}>\n {renderPanelAction({\n id: 'create-invoice',\n fiber,\n state,\n renderAction,\n t,\n defaultProps: {\n id: 'create-invoice',\n label: t('actions.createInvoice', 'Create Invoice (1 CKB)'),\n loadingLabel: t('actions.createInvoice.loading', 'Creating...'),\n disabled: isCreatingInvoice || !isNodeReady,\n loading: isCreatingInvoice,\n onTrigger: createInvoice,\n } satisfies FiberNodeButtonActionDefaultProps,\n })}\n {createdInvoice ? (\n <span style={styles.compactText}>{shorten(createdInvoice, 20, 10)}</span>\n ) : null}\n </div>\n\n <label style={styles.fieldLabel}>\n {t('workbench.payments.invoice', 'Invoice')}\n <input\n style={styles.input}\n value={invoiceInput}\n onChange={(event) => setInvoiceInput(event.target.value)}\n placeholder={t('workbench.payments.invoicePlaceholder', 'Paste invoice to pay')}\n />\n </label>\n\n <div style={styles.rowBetween}>\n {renderPanelAction({\n id: 'pay-invoice',\n fiber,\n state,\n renderAction,\n t,\n buttonStyle: styles.primaryButton,\n defaultProps: {\n id: 'pay-invoice',\n label: t('actions.payInvoice', 'Pay Invoice'),\n loadingLabel: t('actions.payInvoice.loading', 'Paying...'),\n disabled: isPaying || !isNodeReady || !invoiceInput.trim(),\n loading: isPaying,\n onTrigger: submitPayment,\n } satisfies FiberNodeButtonActionDefaultProps,\n })}\n\n <span style={styles.compactText}>\n {t('workbench.payments.status', 'Status')}:{' '}\n {paymentResult?.status ?? t('workbench.payments.idle', 'Idle')}\n </span>\n </div>\n </section>\n </>\n );\n}\n","import type { GetPaymentResult } from '@fiber-pay/sdk/browser';\nimport { type CSSProperties, useEffect, useId, useState } from 'react';\nimport { type UseFiberNodeResult, useFiberNode } from './use-fiber-node.js';\nimport { useFiberPayment } from './use-fiber-payment.js';\n\nexport interface FiberPayQuickCardProps {\n /** Reuse an existing useFiberNode() result instead of creating a new session. */\n fiber?: UseFiberNodeResult;\n network?: 'testnet' | 'mainnet';\n walletId?: string;\n passkeyUsername?: string;\n title?: string;\n className?: string;\n style?: CSSProperties;\n onInvoiceCreated?: (invoice: string) => void;\n onPaymentResult?: (result: GetPaymentResult) => void;\n onError?: (error: { scope: 'node' | 'payment' | 'invoice'; message: string }) => void;\n}\n\nconst ONE_CKB_SHANNONS = '0x5f5e100';\n\nconst cardStyle: CSSProperties = {\n border: '1px solid #ddd',\n borderRadius: 8,\n padding: 16,\n maxWidth: 520,\n};\n\nconst rowStyle: CSSProperties = {\n display: 'flex',\n gap: 8,\n};\n\nconst rowWithMarginStyle: CSSProperties = {\n ...rowStyle,\n marginBottom: 8,\n};\n\nexport function FiberPayQuickCard(props: FiberPayQuickCardProps) {\n const network = props.network ?? 'testnet';\n const passkeyUsername = props.passkeyUsername ?? 'User';\n const title = props.title ?? 'FiberPay Quick Card';\n const usesExternalFiber = !!props.fiber;\n const onError = props.onError;\n const onInvoiceCreated = props.onInvoiceCreated;\n const onPaymentResult = props.onPaymentResult;\n const passwordInputId = useId();\n const invoiceInputId = useId();\n\n const managedFiber = useFiberNode({\n network,\n walletId: props.walletId,\n enabled: !usesExternalFiber,\n });\n\n const fiber = props.fiber ?? managedFiber;\n\n const {\n node,\n nodeInfo,\n state,\n error: nodeError,\n isPasskeySupported,\n hasPasskeyConfigured,\n startWithPassword,\n startWithPasskey,\n createPasskeyAndStart,\n stop,\n } = fiber;\n\n const { payInvoice, isPaying, error: payError, paymentResult } = useFiberPayment(node);\n\n const [password, setPassword] = useState('');\n const [invoiceInput, setInvoiceInput] = useState('');\n const [createdInvoice, setCreatedInvoice] = useState('');\n const [isCreatingInvoice, setIsCreatingInvoice] = useState(false);\n const [invoiceError, setInvoiceError] = useState<string | null>(null);\n\n useEffect(() => {\n if (nodeError) {\n onError?.({ scope: 'node', message: nodeError });\n }\n }, [nodeError, onError]);\n\n useEffect(() => {\n if (payError) {\n onError?.({ scope: 'payment', message: payError });\n }\n }, [onError, payError]);\n\n useEffect(() => {\n if (paymentResult) {\n onPaymentResult?.(paymentResult);\n }\n }, [onPaymentResult, paymentResult]);\n\n const createInvoice = async () => {\n if (!node) {\n return;\n }\n\n setIsCreatingInvoice(true);\n setInvoiceError(null);\n try {\n const created = await node.newInvoice({\n amount: ONE_CKB_SHANNONS,\n currency: network === 'mainnet' ? 'Fibb' : 'Fibt',\n description: 'FiberPay QuickCard invoice',\n });\n setCreatedInvoice(created.invoice_address);\n onInvoiceCreated?.(created.invoice_address);\n } catch (createInvoiceError) {\n const message =\n createInvoiceError instanceof Error\n ? createInvoiceError.message\n : String(createInvoiceError);\n setInvoiceError(message);\n onError?.({ scope: 'invoice', message });\n } finally {\n setIsCreatingInvoice(false);\n }\n };\n\n return (\n <div style={{ ...cardStyle, ...props.style }} className={props.className}>\n <h3>\n {title} ({network})\n </h3>\n\n {!nodeInfo ? (\n usesExternalFiber ? (\n <p>\n <strong>Connection required:</strong> connect the shared node first, then return here to\n create or pay invoices.\n </p>\n ) : (\n <>\n {isPasskeySupported ? (\n <div style={rowWithMarginStyle}>\n {hasPasskeyConfigured ? (\n <button type=\"button\" onClick={() => void startWithPasskey()}>\n Login with Passkey\n </button>\n ) : (\n <button type=\"button\" onClick={() => void createPasskeyAndStart(passkeyUsername)}>\n Register Passkey\n </button>\n )}\n </div>\n ) : null}\n\n <label htmlFor={passwordInputId}>Password</label>\n <div style={rowStyle}>\n <input\n id={passwordInputId}\n type=\"password\"\n autoComplete=\"current-password\"\n aria-label=\"Node password\"\n value={password}\n onChange={(event) => setPassword(event.target.value)}\n placeholder=\"Password\"\n />\n <button type=\"button\" onClick={() => void startWithPassword(password)}>\n Start with Password\n </button>\n </div>\n </>\n )\n ) : (\n <>\n <p>\n <strong>State:</strong> {state}\n </p>\n <p>\n <strong>Pubkey:</strong> {nodeInfo.pubkey}\n </p>\n\n <div style={rowWithMarginStyle}>\n <button type=\"button\" onClick={() => void createInvoice()} disabled={isCreatingInvoice}>\n {isCreatingInvoice ? 'Creating...' : 'Create Invoice (1 CKB)'}\n </button>\n <button type=\"button\" onClick={() => void stop()}>\n Stop Node\n </button>\n </div>\n\n {createdInvoice ? (\n <p>\n <strong>Created invoice:</strong> {createdInvoice}\n </p>\n ) : null}\n\n <label htmlFor={invoiceInputId}>Invoice</label>\n <div style={rowStyle}>\n <input\n id={invoiceInputId}\n aria-label=\"Invoice to pay\"\n value={invoiceInput}\n onChange={(event) => setInvoiceInput(event.target.value)}\n placeholder=\"Paste invoice to pay\"\n />\n <button type=\"button\" onClick={() => void payInvoice(invoiceInput)} disabled={isPaying}>\n {isPaying ? 'Paying...' : 'Pay'}\n </button>\n </div>\n\n {paymentResult ? (\n <p>\n <strong>Payment:</strong> {paymentResult.status}\n </p>\n ) : null}\n </>\n )}\n\n {nodeError ? (\n <p style={{ color: '#b91c1c' }}>\n <strong>Node error:</strong> {nodeError}\n </p>\n ) : null}\n {payError ? (\n <p style={{ color: '#b91c1c' }}>\n <strong>Payment error:</strong> {payError}\n </p>\n ) : null}\n {invoiceError ? (\n <p style={{ color: '#b91c1c' }}>\n <strong>Invoice error:</strong> {invoiceError}\n </p>\n ) : null}\n </div>\n );\n}\n","/**\n * NodeInfoPanel — Displays Fiber browser node metadata, stats, and optional QR code.\n *\n * This is a stateless display component that polls the running node for stats\n * (peer count, channel count, CKB balance) and renders them with copy-to-clipboard\n * support and an optional QR code for the node's CKB address.\n *\n * @example\n * ```tsx\n * import { NodeInfoPanel } from \"@fiber-pay/react\";\n *\n * <NodeInfoPanel node={node} network=\"testnet\" showQrCode />\n * ```\n */\n\nimport type { FiberBrowserNode } from '@fiber-pay/sdk/browser';\nimport {\n ConfigBuilder,\n formatShannonsAsCkb,\n getLockBalanceShannons,\n scriptToAddress,\n} from '@fiber-pay/sdk/browser';\nimport {\n type ComponentType,\n type CSSProperties,\n type ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface NodeInfoPanelProps {\n /** The running FiberBrowserNode instance. */\n node: FiberBrowserNode | null;\n\n /** Network (needed for address derivation and RPC URL defaults). */\n network: 'testnet' | 'mainnet';\n\n /** How often to refresh stats (ms). Default: 15000. */\n pollInterval?: number;\n\n /** Whether to show a QR code of the CKB address. Requires `qrcode.react` to be installed. */\n showQrCode?: boolean;\n\n /**\n * Optional QR code render function — allows consumers to bring their own QR library.\n * Called with the CKB address string. If not provided and `showQrCode` is true,\n * the component will attempt to dynamically import `qrcode.react`.\n */\n renderQrCode?: (value: string) => ReactNode;\n\n /** Additional CSS class name(s). */\n className?: string;\n\n /** Inline styles. */\n style?: CSSProperties;\n}\n\ninterface NodeStats {\n pubkey: string;\n peers: number;\n channels: number;\n ckbAddress: string | null;\n balanceCkb: string | null;\n externalFunding: boolean;\n}\n\n// =============================================================================\n// Helpers\n// =============================================================================\n\nfunction truncateMiddle(str: string, left = 8, right = 8): string {\n if (str.length <= left + right + 3) return str;\n return `${str.slice(0, left)}…${str.slice(-right)}`;\n}\n\nfunction copyToClipboard(text: string) {\n void navigator.clipboard.writeText(text);\n}\n\nasync function fetchNodeStats(\n node: FiberBrowserNode,\n network: 'testnet' | 'mainnet',\n): Promise<NodeStats> {\n const [nodeInfo, peers, channels] = await Promise.all([\n node.nodeInfo(),\n node.listPeers(),\n node.listChannels(),\n ]);\n\n const lockScript = nodeInfo.default_funding_lock_script;\n const ckbRpcUrl = ConfigBuilder.getDefaults(network).ckbRpcUrl;\n\n if (!lockScript || lockScript.args === '0x') {\n return {\n pubkey: nodeInfo.pubkey,\n peers: peers.peers.length,\n channels: channels.channels.length,\n ckbAddress: null,\n balanceCkb: null,\n externalFunding: true,\n };\n }\n\n const ckbAddress = scriptToAddress(lockScript, network);\n const balanceShannons = await getLockBalanceShannons(ckbRpcUrl, lockScript);\n const balanceCkb = formatShannonsAsCkb(balanceShannons, 4);\n\n return {\n pubkey: nodeInfo.pubkey,\n peers: peers.peers.length,\n channels: channels.channels.length,\n ckbAddress,\n balanceCkb,\n externalFunding: false,\n };\n}\n\n// =============================================================================\n// CSS\n// =============================================================================\n\nconst styles = {\n root: {\n fontFamily: 'system-ui, -apple-system, sans-serif',\n fontSize: '0.875rem',\n color: 'var(--fpay-text-primary, #111827)',\n } satisfies CSSProperties,\n\n idle: {\n padding: '1rem',\n textAlign: 'center',\n color: 'var(--fpay-text-secondary, #6b7280)',\n fontSize: '0.75rem',\n } satisfies CSSProperties,\n\n loading: {\n display: 'flex',\n alignItems: 'center',\n gap: '0.5rem',\n padding: '0.5rem 0',\n fontSize: '0.75rem',\n color: 'var(--fpay-text-secondary, #6b7280)',\n } satisfies CSSProperties,\n\n errorBox: {\n marginBottom: '0.5rem',\n padding: '0.375rem 0.5rem',\n fontSize: '0.75rem',\n borderRadius: '0.5rem',\n border: '1px solid var(--fpay-error-border, rgba(239,68,68,0.3))',\n backgroundColor: 'var(--fpay-error-bg, rgba(239,68,68,0.1))',\n color: 'var(--fpay-error, #ef4444)',\n } satisfies CSSProperties,\n\n infoRow: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n gap: '0.75rem',\n padding: '0.375rem 0',\n } satisfies CSSProperties,\n\n infoLabel: {\n fontSize: '0.75rem',\n color: 'var(--fpay-text-secondary, #6b7280)',\n } satisfies CSSProperties,\n\n infoValueWrapper: {\n display: 'flex',\n alignItems: 'center',\n gap: '0.375rem',\n } satisfies CSSProperties,\n\n infoValue: {\n fontFamily: 'ui-monospace, monospace',\n fontSize: '0.75rem',\n color: 'var(--fpay-text-primary, #111827)',\n } satisfies CSSProperties,\n\n copyButton: {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '0.25rem',\n borderRadius: '0.25rem',\n border: 'none',\n background: 'none',\n cursor: 'pointer',\n color: 'var(--fpay-text-secondary, #6b7280)',\n transition: 'color 0.15s',\n } satisfies CSSProperties,\n\n statsGrid: {\n display: 'grid',\n gridTemplateColumns: '1fr 1fr',\n gap: '0.5rem',\n marginTop: '0.5rem',\n } satisfies CSSProperties,\n\n statCard: {\n padding: '0.375rem 0.5rem',\n textAlign: 'center',\n borderRadius: '0.5rem',\n border: '1px solid var(--fpay-border, #e5e7eb)',\n backgroundColor: 'var(--fpay-bg-secondary, #f9fafb)',\n } satisfies CSSProperties,\n\n statLabel: {\n fontSize: '0.625rem',\n color: 'var(--fpay-text-secondary, #6b7280)',\n } satisfies CSSProperties,\n\n statValue: {\n fontSize: '0.875rem',\n fontWeight: 600,\n color: 'var(--fpay-text-primary, #111827)',\n } satisfies CSSProperties,\n\n qrContainer: {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: '0.25rem',\n marginTop: '0.75rem',\n padding: '0.5rem',\n borderRadius: '0.5rem',\n border: '1px solid var(--fpay-border, #e5e7eb)',\n backgroundColor: 'var(--fpay-bg-secondary, #f9fafb)',\n } satisfies CSSProperties,\n\n qrCaption: {\n fontSize: '0.625rem',\n color: 'var(--fpay-text-secondary, #6b7280)',\n } satisfies CSSProperties,\n\n balanceRow: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n width: '100%',\n marginTop: '0.5rem',\n paddingTop: '0.5rem',\n borderTop: '1px solid var(--fpay-border, #e5e7eb)',\n } satisfies CSSProperties,\n\n statusBadge: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '0.375rem',\n padding: '0.25rem 0.625rem',\n fontSize: '0.75rem',\n fontWeight: 500,\n borderRadius: '9999px',\n marginBottom: '0.5rem',\n } satisfies CSSProperties,\n};\n\nconst STATUS_COLORS: Record<string, { bg: string; fg: string; dot: string }> = {\n idle: { bg: 'rgba(107,114,128,0.1)', fg: '#6b7280', dot: '#9ca3af' },\n unlocking: { bg: 'rgba(245,158,11,0.1)', fg: '#d97706', dot: '#f59e0b' },\n starting: { bg: 'rgba(245,158,11,0.1)', fg: '#d97706', dot: '#f59e0b' },\n running: { bg: 'rgba(34,197,94,0.1)', fg: '#16a34a', dot: '#22c55e' },\n stopping: { bg: 'rgba(245,158,11,0.1)', fg: '#d97706', dot: '#f59e0b' },\n stopped: { bg: 'rgba(107,114,128,0.1)', fg: '#6b7280', dot: '#9ca3af' },\n error: { bg: 'rgba(239,68,68,0.1)', fg: '#dc2626', dot: '#ef4444' },\n};\n\n// =============================================================================\n// Sub-components\n// =============================================================================\n\nfunction CopyIcon() {\n return (\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" />\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\n </svg>\n );\n}\n\nfunction InfoRow({ label, value, copyable }: { label: string; value: string; copyable?: boolean }) {\n return (\n <div style={styles.infoRow}>\n <span style={styles.infoLabel}>{label}</span>\n <div style={styles.infoValueWrapper}>\n <span style={styles.infoValue}>{truncateMiddle(value, 6, 6)}</span>\n {copyable && (\n <button\n type=\"button\"\n onClick={() => copyToClipboard(value)}\n style={styles.copyButton}\n title=\"Copy to clipboard\"\n aria-label={`Copy ${label}`}\n >\n <CopyIcon />\n </button>\n )}\n </div>\n </div>\n );\n}\n\n// =============================================================================\n// Component\n// =============================================================================\n\nexport function NodeInfoPanel(props: NodeInfoPanelProps) {\n const {\n node,\n network,\n pollInterval = 15000,\n showQrCode = false,\n renderQrCode,\n className,\n style,\n } = props;\n\n const [stats, setStats] = useState<NodeStats | null>(null);\n const [statsError, setStatsError] = useState<string | null>(null);\n const [statsLoading, setStatsLoading] = useState(false);\n const cancelledRef = useRef(false);\n\n // QR code dynamic import state\n const [QRComponent, setQRComponent] = useState<ComponentType<{\n value: string;\n size?: number;\n bgColor?: string;\n fgColor?: string;\n }> | null>(null);\n\n // Attempt to dynamically import qrcode.react if needed\n useEffect(() => {\n let cancelled = false;\n if (!showQrCode || renderQrCode) return;\n import('qrcode.react')\n .then((mod: Record<string, unknown>) => {\n if (cancelled) return;\n const Comp = (mod.QRCodeSVG ?? mod.default) as\n | ComponentType<{\n value: string;\n size?: number;\n bgColor?: string;\n fgColor?: string;\n }>\n | undefined;\n if (Comp) setQRComponent(() => Comp);\n })\n .catch(() => {\n // qrcode.react not installed — silently skip\n });\n return () => {\n cancelled = true;\n };\n }, [showQrCode, renderQrCode]);\n\n const loadingRef = useRef(false);\n\n const loadStats = useCallback(async () => {\n if (!node || node.state !== 'running' || loadingRef.current) return;\n loadingRef.current = true;\n setStatsLoading(true);\n setStatsError(null);\n try {\n const data = await fetchNodeStats(node, network);\n if (!cancelledRef.current) setStats(data);\n } catch (e) {\n if (!cancelledRef.current) {\n setStatsError(e instanceof Error ? e.message : String(e));\n }\n } finally {\n loadingRef.current = false;\n if (!cancelledRef.current) setStatsLoading(false);\n }\n }, [node, network]);\n\n useEffect(() => {\n cancelledRef.current = false;\n\n if (!node || node.state !== 'running') {\n setStats(null);\n setStatsError(null);\n return;\n }\n\n void loadStats();\n const interval = setInterval(() => void loadStats(), pollInterval);\n return () => {\n cancelledRef.current = true;\n clearInterval(interval);\n };\n }, [node, node?.state, pollInterval, loadStats]);\n\n // --- Render ---------------------------------------------------------------\n\n if (!node) {\n return (\n <div className={className} style={{ ...styles.root, ...style }} data-fpay-node-info=\"\">\n <div style={styles.idle}>No node connected</div>\n </div>\n );\n }\n\n const nodeState = node.state;\n const statusColor = STATUS_COLORS[nodeState] ?? STATUS_COLORS.idle;\n\n return (\n <div className={className} style={{ ...styles.root, ...style }} data-fpay-node-info=\"\">\n {/* Status badge */}\n <div\n style={{\n ...styles.statusBadge,\n backgroundColor: statusColor.bg,\n color: statusColor.fg,\n }}\n >\n <span\n style={{\n display: 'inline-block',\n width: '0.5rem',\n height: '0.5rem',\n borderRadius: '50%',\n backgroundColor: statusColor.dot,\n }}\n />\n {nodeState}\n </div>\n\n {/* Loading indicator */}\n {statsLoading && !stats && (\n <div style={styles.loading}>\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n role=\"img\"\n aria-label=\"Loading\"\n >\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n <animateTransform\n attributeName=\"transform\"\n type=\"rotate\"\n from=\"0 12 12\"\n to=\"360 12 12\"\n dur=\"1s\"\n repeatCount=\"indefinite\"\n />\n </svg>\n Loading…\n </div>\n )}\n\n {/* Error */}\n {statsError && <div style={styles.errorBox}>{statsError}</div>}\n\n {/* Stats */}\n {stats && (\n <>\n <InfoRow label=\"Pubkey\" value={stats.pubkey} copyable />\n\n {stats.externalFunding ? (\n <div style={{ padding: '0.25rem 0', fontSize: '0.75rem', color: '#6b7280' }}>\n External funding mode\n </div>\n ) : stats.ckbAddress ? (\n <InfoRow label=\"CKB Address\" value={stats.ckbAddress} copyable />\n ) : null}\n\n <div style={styles.statsGrid}>\n <div style={styles.statCard}>\n <div style={styles.statLabel}>Peers</div>\n <div style={styles.statValue}>{stats.peers}</div>\n </div>\n <div style={styles.statCard}>\n <div style={styles.statLabel}>Channels</div>\n <div style={styles.statValue}>{stats.channels}</div>\n </div>\n </div>\n\n {/* QR Code */}\n {showQrCode && stats.ckbAddress && (\n <div style={styles.qrContainer}>\n {renderQrCode ? (\n renderQrCode(stats.ckbAddress)\n ) : QRComponent ? (\n <QRComponent\n value={stats.ckbAddress}\n size={120}\n bgColor=\"transparent\"\n fgColor=\"currentColor\"\n />\n ) : (\n <div style={{ fontSize: '0.625rem', color: '#9ca3af' }}>\n Install qrcode.react for QR code\n </div>\n )}\n <span style={styles.qrCaption}>Scan to deposit CKB</span>\n <div style={styles.balanceRow}>\n <span style={{ fontSize: '0.75rem', color: '#6b7280' }}>Balance</span>\n <span\n style={{\n fontFamily: 'ui-monospace, monospace',\n fontSize: '0.75rem',\n fontWeight: 500,\n }}\n >\n {stats.balanceCkb ?? '—'} CKB\n </span>\n </div>\n </div>\n )}\n </>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":["ChannelState","ConfigBuilder","ckbToShannons","FiberBrowserNode","formatShannonsAsCkb","getLockBalanceShannons","PasskeyCredentialProvider","PasswordCredentialProvider","RawKeyCredentialProvider","scriptToAddress","shannonsToCkb","useCallback","useEffect","useRef","useState","useState","useRef","useEffect","useCallback","useCallback","useEffect","useMemo","useRef","styles","jsx","styles","Fragment","jsx","jsxs","styles","Fragment","jsx","jsxs","styles","ChannelState","useCallback","useEffect","useId","useMemo","useRef","useState","useCallback","useMemo","useState","toHexPrefixed","result","useCallback","useEffect","useRef","useState","asErrorMessage","useState","useRef","useId","useEffect","useCallback","ChannelState","openResult","useMemo","Fragment","jsx","jsxs","styles","Fragment","jsx","jsxs","useRef","useMemo","styles","useEffect","jsx","useCallback","useEffect","useId","useState","Fragment","jsx","jsxs","ONE_CKB_SHANNONS","useId","useState","useEffect","useCallback","useEffect","useRef","useState","Fragment","jsx","jsxs","styles"]}