@fiber-pay/react 0.2.3 → 0.2.4
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/README.md +37 -1
- package/dist/index.d.ts +106 -19
- package/dist/index.js +886 -51
- package/dist/index.js.map +1 -1
- package/package.json +9 -3
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/fiber-pay-quick-card.tsx","../src/use-fiber-node.ts","../src/use-fiber-payment.ts"],"sourcesContent":["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 {\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} from '@fiber-pay/sdk/browser';\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nexport interface UseFiberNodeOptions {\n network: 'testnet' | 'mainnet';\n walletId?: string;\n nodeConfig?: FiberBrowserNodeConfig['nodeConfig'];\n wasmFactory?: FiberWasmFactory;\n}\n\nexport interface UseFiberNodeResult {\n state: BrowserNodeState;\n node: FiberBrowserNode | null;\n nodeInfo: NodeInfoResult | null;\n error: string | null;\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 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 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]);\n\n const initNode = useCallback(\n (credential: PasswordCredentialProvider | PasskeyCredentialProvider) => {\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 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 return {\n state,\n node: nodeRef.current,\n nodeInfo,\n error,\n isPasskeySupported,\n passkeySupportReason,\n passkeyUnavailableReason,\n hasPasskeyConfigured,\n startWithPassword,\n createPasskeyAndStart,\n startWithPasskey,\n stop,\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"],"mappings":";AACA,SAA6B,aAAAA,YAAW,OAAO,YAAAC,iBAAgB;;;ACD/D;AAAA,EAEE;AAAA,EAIA;AAAA,EAGA;AAAA,OACK;AACP,SAAS,aAAa,WAAW,QAAQ,gBAAgB;AAwBzD,IAAM,kCAGF;AAAA,EACF,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,wBAAwB;AAAA,EACxB,mBAAmB;AAAA,EACnB,SAAS;AACX;AAEO,SAAS,8BAA8B,QAAuC;AACnF,SAAO,OAAO,aAAa,OAAO,WAAW;AAC/C;AAEO,SAAS,2BAA2B,QAA6C;AACtF,MAAI,WAAW,aAAa;AAC1B,WAAO;AAAA,EACT;AACA,SAAO,gCAAgC,MAAM;AAC/C;AAEA,SAAS,eAAe,OAAwB;AAC9C,MAAI,iBAAiB,OAAO;AAC1B,WAAO,MAAM;AAAA,EACf;AACA,SAAO,OAAO,KAAK;AACrB;AAOO,SAAS,aAAa,SAAkD;AAC7E,QAAM,WAAW,QAAQ,YAAY,UAAU,QAAQ,OAAO;AAC9D,QAAM,CAAC,OAAO,QAAQ,IAAI,SAA2B,MAAM;AAC3D,QAAM,CAAC,UAAU,WAAW,IAAI,SAAgC,IAAI;AACpE,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAwB,IAAI;AACtD,QAAM,CAAC,oBAAoB,qBAAqB,IAAI,SAAS,KAAK;AAClE,QAAM,CAAC,sBAAsB,uBAAuB,IAAI;AAAA,IACtD;AAAA,EACF;AACA,QAAM,CAAC,0BAA0B,2BAA2B,IAAI,SAAwB,IAAI;AAC5F,QAAM,CAAC,sBAAsB,uBAAuB,IAAI,SAAS,KAAK;AAEtE,QAAM,UAAU,OAAgC,IAAI;AACpD,QAAM,eAAe,OAAO,IAAI;AAChC,QAAM,mBAAmB,OAAkC,IAAI;AAE/D,QAAM,sBAAsB,YAAY,CAAC,SAAkC;AACzE,QAAI,CAAC,QAAQ,CAAC,iBAAiB,SAAS;AACtC;AAAA,IACF;AAEA,SAAK,IAAI,eAAe,iBAAiB,QAAQ,WAAW;AAC5D,SAAK,IAAI,SAAS,iBAAiB,QAAQ,KAAK;AAChD,qBAAiB,UAAU;AAAA,EAC7B,GAAG,CAAC,CAAC;AAEL;AAAA,IACE,MAAM,MAAM;AACV,mBAAa,UAAU;AAEvB,YAAM,OAAO,QAAQ;AACrB,cAAQ,UAAU;AAElB,UAAI,MAAM;AACR,4BAAoB,IAAI;AACxB,aAAK,KAAK,KAAK,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AAAA,MACjC;AAAA,IACF;AAAA,IACA,CAAC,mBAAmB;AAAA,EACtB;AAEA,YAAU,MAAM;AACd,QAAI,YAAY;AAEhB,8BAA0B,iBAAiB,EACxC,KAAK,CAAC,WAAW;AAChB,UAAI,CAAC,WAAW;AACd,cAAM,YAAY,8BAA8B,MAAM;AACtD,8BAAsB,SAAS;AAC/B,gCAAwB,OAAO,MAAM;AACrC,oCAA4B,YAAY,OAAO,2BAA2B,OAAO,MAAM,CAAC;AAAA,MAC1F;AAAA,IACF,CAAC,EACA,MAAM,CAAC,iBAAiB;AACvB,UAAI,CAAC,WAAW;AACd,8BAAsB,KAAK;AAC3B,gCAAwB,SAAS;AACjC,oCAA4B,2BAA2B,SAAS,CAAC;AAAA,MACnE;AAEA,UAAI,wBAAwB,OAAO;AACjC,gBAAQ,KAAK,uDAAuD,aAAa,OAAO;AAAA,MAC1F;AAAA,IACF,CAAC;AAEH,UAAM,WAAW,IAAI,0BAA0B,QAAQ;AACvD,4BAAwB,SAAS,aAAa,CAAC;AAE/C,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,QAAQ,CAAC;AAEb,QAAM,WAAW;AAAA,IACf,CAAC,eAAuE;AACtE,UAAI,QAAQ,SAAS;AACnB,cAAM,gBAAgB,QAAQ,QAAQ;AACtC,YAAI,kBAAkB,UAAU,kBAAkB,aAAa,kBAAkB,SAAS;AACxF,gBAAM,IAAI,MAAM,sBAAsB;AAAA,QACxC;AAEA,4BAAoB,QAAQ,OAAO;AACnC,gBAAQ,UAAU;AAAA,MACpB;AAEA,YAAM,aAAgE;AAAA,QACpE,SAAS,QAAQ;AAAA,QACjB;AAAA,QACA,YAAY;AAAA,UACV,gBAAgB,IAAI,QAAQ;AAAA,UAC5B,GAAI,QAAQ,cAAc,CAAC;AAAA,QAC7B;AAAA,MACF;AAEA,UAAI,QAAQ,aAAa;AACvB,mBAAW,cAAc,QAAQ;AAAA,MACnC;AAEA,YAAM,OAAO,IAAI,iBAAiB,UAAU;AAE5C,cAAQ,UAAU;AAElB,YAAM,YAAgC;AAAA,QACpC,aAAa,CAAC,cAAc;AAC1B,cAAI,CAAC,aAAa,SAAS;AACzB;AAAA,UACF;AAEA,mBAAS,SAAS;AAClB,cAAI,cAAc,WAAW;AAC3B,wBAAY,IAAI;AAAA,UAClB;AAAA,QACF;AAAA,QACA,OAAO,CAAC,cAAqB;AAC3B,cAAI,CAAC,aAAa,SAAS;AACzB;AAAA,UACF;AAEA,mBAAS,UAAU,OAAO;AAAA,QAC5B;AAAA,MACF;AAEA,uBAAiB,UAAU;AAC3B,WAAK,GAAG,eAAe,UAAU,WAAW;AAC5C,WAAK,GAAG,SAAS,UAAU,KAAK;AAEhC,aAAO;AAAA,IACT;AAAA,IACA,CAAC,qBAAqB,QAAQ,SAAS,QAAQ,YAAY,QAAQ,aAAa,QAAQ;AAAA,EAC1F;AAEA,QAAM,qBAAqB;AAAA,IACzB,OAAO,SAAkC;AACvC,UAAI,CAAC,MAAM;AACT;AAAA,MACF;AAEA,UAAI;AACF,YAAI,KAAK,UAAU,UAAU,KAAK,UAAU,WAAW;AACrD,gBAAM,KAAK,KAAK;AAAA,QAClB;AAAA,MACF,QAAQ;AAAA,MAER,UAAE;AACA,4BAAoB,IAAI;AACxB,YAAI,QAAQ,YAAY,MAAM;AAC5B,kBAAQ,UAAU;AAAA,QACpB;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,mBAAmB;AAAA,EACtB;AAEA,QAAM,oBAAoB;AAAA,IACxB,OAAO,aAAqB;AAC1B,eAAS,IAAI;AACb,UAAI,OAAgC;AAEpC,UAAI;AACF,cAAM,aAAa,IAAI,2BAA2B,QAAQ;AAC1D,eAAO,SAAS,UAAU;AAC1B,cAAM,OAAO,MAAM,KAAK,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,CAAC;AAC5D,YAAI,aAAa,SAAS;AACxB,sBAAY,IAAI;AAAA,QAClB;AAAA,MACF,SAAS,YAAY;AACnB,YAAI,aAAa,SAAS;AACxB,mBAAS,eAAe,UAAU,CAAC;AAAA,QACrC;AAEA,cAAM,mBAAmB,IAAI;AAAA,MAC/B;AAAA,IACF;AAAA,IACA,CAAC,oBAAoB,UAAU,QAAQ;AAAA,EACzC;AAEA,QAAM,wBAAwB;AAAA,IAC5B,OAAO,WAAW,WAAW;AAC3B,eAAS,IAAI;AACb,UAAI,OAAgC;AAEpC,UAAI;AACF,cAAM,aAAa,IAAI,0BAA0B,QAAQ;AACzD,cAAM,WAAW,SAAS,QAAQ;AAClC,YAAI,aAAa,SAAS;AACxB,kCAAwB,IAAI;AAAA,QAC9B;AAEA,eAAO,SAAS,UAAU;AAC1B,cAAM,OAAO,MAAM,KAAK,MAAM;AAC9B,YAAI,aAAa,SAAS;AACxB,sBAAY,IAAI;AAAA,QAClB;AAAA,MACF,SAAS,YAAY;AACnB,YAAI,aAAa,SAAS;AACxB,mBAAS,eAAe,UAAU,CAAC;AAAA,QACrC;AAEA,cAAM,mBAAmB,IAAI;AAAA,MAC/B;AAAA,IACF;AAAA,IACA,CAAC,oBAAoB,UAAU,QAAQ;AAAA,EACzC;AAEA,QAAM,mBAAmB,YAAY,YAAY;AAC/C,aAAS,IAAI;AACb,QAAI,OAAgC;AAEpC,QAAI;AACF,YAAM,aAAa,IAAI,0BAA0B,QAAQ;AACzD,aAAO,SAAS,UAAU;AAC1B,YAAM,OAAO,MAAM,KAAK,MAAM;AAC9B,UAAI,aAAa,SAAS;AACxB,oBAAY,IAAI;AAAA,MAClB;AAAA,IACF,SAAS,YAAY;AACnB,UAAI,aAAa,SAAS;AACxB,iBAAS,eAAe,UAAU,CAAC;AAAA,MACrC;AAEA,YAAM,mBAAmB,IAAI;AAAA,IAC/B;AAAA,EACF,GAAG,CAAC,oBAAoB,UAAU,QAAQ,CAAC;AAE3C,QAAM,OAAO,YAAY,YAAY;AACnC,UAAM,OAAO,QAAQ;AACrB,QAAI,CAAC,MAAM;AACT;AAAA,IACF;AAEA,QAAI;AACF,YAAM,KAAK,KAAK;AAAA,IAClB,SAAS,WAAW;AAClB,UAAI,aAAa,SAAS;AACxB,iBAAS,eAAe,SAAS,CAAC;AAAA,MACpC;AAAA,IACF,UAAE;AACA,0BAAoB,IAAI;AACxB,UAAI,QAAQ,YAAY,MAAM;AAC5B,gBAAQ,UAAU;AAAA,MACpB;AAEA,UAAI,aAAa,SAAS;AACxB,oBAAY,IAAI;AAAA,MAClB;AAAA,IACF;AAAA,EACF,GAAG,CAAC,mBAAmB,CAAC;AAExB,SAAO;AAAA,IACL;AAAA,IACA,MAAM,QAAQ;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AC1UA,SAAS,eAAAC,cAAa,aAAAC,YAAW,UAAAC,SAAQ,YAAAC,iBAAgB;AASzD,SAASC,gBAAe,OAAwB;AAC9C,MAAI,iBAAiB,OAAO;AAC1B,WAAO,MAAM;AAAA,EACf;AACA,SAAO,OAAO,KAAK;AACrB;AAEO,SAAS,gBAAgB,MAAsD;AACpF,QAAM,CAAC,UAAU,WAAW,IAAID,UAAS,KAAK;AAC9C,QAAM,CAAC,eAAe,gBAAgB,IAAIA,UAAkC,IAAI;AAChF,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAwB,IAAI;AACtD,QAAM,eAAeD,QAAO,IAAI;AAEhC,EAAAD;AAAA,IACE,MAAM,MAAM;AACV,mBAAa,UAAU;AAAA,IACzB;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,aAAaD;AAAA,IACjB,OAAO,YAAoB;AACzB,UAAI,CAAC,MAAM;AACT,YAAI,aAAa,SAAS;AACxB,mBAAS,yBAAyB;AAAA,QACpC;AACA;AAAA,MACF;AAEA,UAAI,aAAa,SAAS;AACxB,oBAAY,IAAI;AAChB,iBAAS,IAAI;AACb,yBAAiB,IAAI;AAAA,MACvB;AAEA,UAAI;AACF,cAAM,SAAS,MAAM,KAAK,aAAa,EAAE,QAAQ,CAAC;AAClD,cAAM,KAAK,YAAY,EAAE,QAAQ,CAAC;AAElC,cAAM,cAAc,OAAO,QAAQ,KAAK;AACxC,cAAM,SAAS,MAAM,KAAK,eAAe,WAAW;AAEpD,YAAI,OAAO,WAAW,UAAU;AAC9B,gBAAM,IAAI,MAAM,OAAO,gBAAgB,yCAAyC;AAAA,QAClF;AAEA,YAAI,aAAa,SAAS;AACxB,2BAAiB,MAAM;AAAA,QACzB;AAAA,MACF,SAAS,UAAU;AACjB,YAAI,aAAa,SAAS;AACxB,mBAASI,gBAAe,QAAQ,CAAC;AAAA,QACnC;AAAA,MACF,UAAE;AACA,YAAI,aAAa,SAAS;AACxB,sBAAY,KAAK;AAAA,QACnB;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,IAAI;AAAA,EACP;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AFoCM,SAKE,UAIQ,KATV;AAjGN,IAAM,mBAAmB;AAEzB,IAAM,YAA2B;AAAA,EAC/B,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,SAAS;AAAA,EACT,UAAU;AACZ;AAEA,IAAM,WAA0B;AAAA,EAC9B,SAAS;AAAA,EACT,KAAK;AACP;AAEA,IAAM,qBAAoC;AAAA,EACxC,GAAG;AAAA,EACH,cAAc;AAChB;AAEO,SAAS,kBAAkB,OAA+B;AAC/D,QAAM,UAAU,MAAM,WAAW;AACjC,QAAM,kBAAkB,MAAM,mBAAmB;AACjD,QAAM,QAAQ,MAAM,SAAS;AAC7B,QAAM,UAAU,MAAM;AACtB,QAAM,mBAAmB,MAAM;AAC/B,QAAM,kBAAkB,MAAM;AAC9B,QAAM,kBAAkB,MAAM;AAC9B,QAAM,iBAAiB,MAAM;AAE7B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,aAAa,EAAE,SAAS,UAAU,MAAM,SAAS,CAAC;AAEtD,QAAM,EAAE,YAAY,UAAU,OAAO,UAAU,cAAc,IAAI,gBAAgB,IAAI;AAErF,QAAM,CAAC,UAAU,WAAW,IAAIC,UAAS,EAAE;AAC3C,QAAM,CAAC,cAAc,eAAe,IAAIA,UAAS,EAAE;AACnD,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,UAAS,EAAE;AACvD,QAAM,CAAC,mBAAmB,oBAAoB,IAAIA,UAAS,KAAK;AAChE,QAAM,CAAC,cAAc,eAAe,IAAIA,UAAwB,IAAI;AAEpE,EAAAC,WAAU,MAAM;AACd,QAAI,WAAW;AACb,gBAAU,EAAE,OAAO,QAAQ,SAAS,UAAU,CAAC;AAAA,IACjD;AAAA,EACF,GAAG,CAAC,WAAW,OAAO,CAAC;AAEvB,EAAAA,WAAU,MAAM;AACd,QAAI,UAAU;AACZ,gBAAU,EAAE,OAAO,WAAW,SAAS,SAAS,CAAC;AAAA,IACnD;AAAA,EACF,GAAG,CAAC,SAAS,QAAQ,CAAC;AAEtB,EAAAA,WAAU,MAAM;AACd,QAAI,eAAe;AACjB,wBAAkB,aAAa;AAAA,IACjC;AAAA,EACF,GAAG,CAAC,iBAAiB,aAAa,CAAC;AAEnC,QAAM,gBAAgB,YAAY;AAChC,QAAI,CAAC,MAAM;AACT;AAAA,IACF;AAEA,yBAAqB,IAAI;AACzB,oBAAgB,IAAI;AACpB,QAAI;AACF,YAAM,UAAU,MAAM,KAAK,WAAW;AAAA,QACpC,QAAQ;AAAA,QACR,UAAU,YAAY,YAAY,SAAS;AAAA,QAC3C,aAAa;AAAA,MACf,CAAC;AACD,wBAAkB,QAAQ,eAAe;AACzC,yBAAmB,QAAQ,eAAe;AAAA,IAC5C,SAAS,oBAAoB;AAC3B,YAAM,UACJ,8BAA8B,QAC1B,mBAAmB,UACnB,OAAO,kBAAkB;AAC/B,sBAAgB,OAAO;AACvB,gBAAU,EAAE,OAAO,WAAW,QAAQ,CAAC;AAAA,IACzC,UAAE;AACA,2BAAqB,KAAK;AAAA,IAC5B;AAAA,EACF;AAEA,SACE,qBAAC,SAAI,OAAO,EAAE,GAAG,WAAW,GAAG,MAAM,MAAM,GAAG,WAAW,MAAM,WAC7D;AAAA,yBAAC,QACE;AAAA;AAAA,MAAM;AAAA,MAAG;AAAA,MAAQ;AAAA,OACpB;AAAA,IAEC,CAAC,WACA,iCACG;AAAA,2BACC,oBAAC,SAAI,OAAO,oBACT,iCACC,oBAAC,YAAO,MAAK,UAAS,SAAS,MAAM,KAAK,iBAAiB,GAAG,gCAE9D,IAEA,oBAAC,YAAO,MAAK,UAAS,SAAS,MAAM,KAAK,sBAAsB,eAAe,GAAG,8BAElF,GAEJ,IACE;AAAA,MAEJ,oBAAC,WAAM,SAAS,iBAAiB,sBAAQ;AAAA,MACzC,qBAAC,SAAI,OAAO,UACV;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,IAAI;AAAA,YACJ,MAAK;AAAA,YACL,cAAa;AAAA,YACb,cAAW;AAAA,YACX,OAAO;AAAA,YACP,UAAU,CAAC,UAAU,YAAY,MAAM,OAAO,KAAK;AAAA,YACnD,aAAY;AAAA;AAAA,QACd;AAAA,QACA,oBAAC,YAAO,MAAK,UAAS,SAAS,MAAM,KAAK,kBAAkB,QAAQ,GAAG,iCAEvE;AAAA,SACF;AAAA,OACF,IAEA,iCACE;AAAA,2BAAC,OACC;AAAA,4BAAC,YAAO,oBAAM;AAAA,QAAS;AAAA,QAAE;AAAA,SAC3B;AAAA,MACA,qBAAC,OACC;AAAA,4BAAC,YAAO,qBAAO;AAAA,QAAS;AAAA,QAAE,SAAS;AAAA,SACrC;AAAA,MAEA,qBAAC,SAAI,OAAO,oBACV;AAAA,4BAAC,YAAO,MAAK,UAAS,SAAS,MAAM,KAAK,cAAc,GAAG,UAAU,mBAClE,8BAAoB,gBAAgB,0BACvC;AAAA,QACA,oBAAC,YAAO,MAAK,UAAS,SAAS,MAAM,KAAK,KAAK,GAAG,uBAElD;AAAA,SACF;AAAA,MAEC,iBACC,qBAAC,OACC;AAAA,4BAAC,YAAO,8BAAgB;AAAA,QAAS;AAAA,QAAE;AAAA,SACrC,IACE;AAAA,MAEJ,oBAAC,WAAM,SAAS,gBAAgB,qBAAO;AAAA,MACvC,qBAAC,SAAI,OAAO,UACV;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,IAAI;AAAA,YACJ,cAAW;AAAA,YACX,OAAO;AAAA,YACP,UAAU,CAAC,UAAU,gBAAgB,MAAM,OAAO,KAAK;AAAA,YACvD,aAAY;AAAA;AAAA,QACd;AAAA,QACA,oBAAC,YAAO,MAAK,UAAS,SAAS,MAAM,KAAK,WAAW,YAAY,GAAG,UAAU,UAC3E,qBAAW,cAAc,OAC5B;AAAA,SACF;AAAA,MAEC,gBACC,qBAAC,OACC;AAAA,4BAAC,YAAO,sBAAQ;AAAA,QAAS;AAAA,QAAE,cAAc;AAAA,SAC3C,IACE;AAAA,OACN;AAAA,IAGD,YACC,qBAAC,OAAE,OAAO,EAAE,OAAO,UAAU,GAC3B;AAAA,0BAAC,YAAO,yBAAW;AAAA,MAAS;AAAA,MAAE;AAAA,OAChC,IACE;AAAA,IACH,WACC,qBAAC,OAAE,OAAO,EAAE,OAAO,UAAU,GAC3B;AAAA,0BAAC,YAAO,4BAAc;AAAA,MAAS;AAAA,MAAE;AAAA,OACnC,IACE;AAAA,IACH,eACC,qBAAC,OAAE,OAAO,EAAE,OAAO,UAAU,GAC3B;AAAA,0BAAC,YAAO,4BAAc;AAAA,MAAS;AAAA,MAAE;AAAA,OACnC,IACE;AAAA,KACN;AAEJ;","names":["useEffect","useState","useCallback","useEffect","useRef","useState","asErrorMessage","useState","useEffect"]}
|
|
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"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fiber-pay/react",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "React hooks and components for Fiber browser payments",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -33,10 +33,16 @@
|
|
|
33
33
|
"sideEffects": false,
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@nervosnetwork/fiber-js": "~0.8.0",
|
|
36
|
-
"@fiber-pay/sdk": "0.2.
|
|
36
|
+
"@fiber-pay/sdk": "0.2.4"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"react": "^18.0.0 || ^19.0.0"
|
|
39
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
40
|
+
"qrcode.react": "^4.0.0"
|
|
41
|
+
},
|
|
42
|
+
"peerDependenciesMeta": {
|
|
43
|
+
"qrcode.react": {
|
|
44
|
+
"optional": true
|
|
45
|
+
}
|
|
40
46
|
},
|
|
41
47
|
"devDependencies": {
|
|
42
48
|
"@types/react": "^18.0.0 || ^19.0.0"
|