@fiber-pay/cli 0.1.0-rc.5 → 0.1.0-rc.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/cli.js +298 -17
- package/dist/cli.js.map +1 -1
- package/package.json +4 -4
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/commands/binary.ts","../src/lib/binary-path.ts","../src/lib/node-runtime-daemon.ts","../src/lib/format.ts","../src/commands/channel.ts","../src/lib/async.ts","../src/lib/rpc.ts","../src/lib/pid.ts","../src/lib/runtime-meta.ts","../src/lib/runtime-jobs.ts","../src/commands/rebalance.ts","../src/commands/config.ts","../src/lib/config.ts","../src/lib/config-templates.ts","../src/commands/graph.ts","../src/commands/invoice.ts","../src/commands/job.ts","../src/lib/log-files.ts","../src/commands/logs.ts","../src/commands/node.ts","../src/lib/node-start.ts","../src/lib/bootnode.ts","../src/lib/node-migration.ts","../src/lib/migration-utils.ts","../src/lib/runtime-port.ts","../src/lib/node-status.ts","../src/lib/node-recommendation.ts","../src/lib/node-rpc.ts","../src/lib/node-stop.ts","../src/lib/node-upgrade.ts","../src/commands/payment.ts","../src/commands/peer.ts","../src/commands/runtime.ts","../src/lib/parse-options.ts","../src/commands/version.ts","../src/lib/build-info.ts","../src/lib/argv.ts"],"sourcesContent":["import { join } from 'node:path';\nimport { Command } from 'commander';\nimport { createBinaryCommand } from './commands/binary.js';\nimport { createChannelCommand } from './commands/channel.js';\nimport { createConfigCommand } from './commands/config.js';\nimport { createGraphCommand } from './commands/graph.js';\nimport { createInvoiceCommand } from './commands/invoice.js';\nimport { createJobCommand } from './commands/job.js';\nimport { createLogsCommand } from './commands/logs.js';\nimport { createNodeCommand } from './commands/node.js';\nimport { createPaymentCommand } from './commands/payment.js';\nimport { createPeerCommand } from './commands/peer.js';\nimport { createRuntimeCommand } from './commands/runtime.js';\nimport { createVersionCommand } from './commands/version.js';\nimport { isTopLevelVersionRequest } from './lib/argv.js';\nimport { CLI_COMMIT, CLI_VERSION } from './lib/build-info.js';\nimport { getEffectiveConfig } from './lib/config.js';\nimport { printJsonError } from './lib/format.js';\n\nfunction shouldOutputJson(): boolean {\n return process.argv.includes('--json');\n}\n\nfunction getFlagValue(argv: string[], index: number): string | undefined {\n const value = argv[index + 1];\n if (!value || value.startsWith('-')) {\n return undefined;\n }\n return value;\n}\n\n/** Tracks which config keys were explicitly set via CLI flags. */\nconst explicitFlags = new Set<string>();\n\nfunction applyGlobalOverrides(argv: string[]): void {\n let explicitDataDir = false;\n let profileName: string | undefined;\n explicitFlags.clear();\n\n for (let index = 0; index < argv.length; index++) {\n const arg = argv[index];\n switch (arg) {\n case '--profile': {\n const value = getFlagValue(argv, index);\n if (value) profileName = value;\n break;\n }\n case '--data-dir': {\n const value = getFlagValue(argv, index);\n if (value) {\n process.env.FIBER_DATA_DIR = value;\n explicitDataDir = true;\n explicitFlags.add('dataDir');\n }\n break;\n }\n case '--rpc-url': {\n const value = getFlagValue(argv, index);\n if (value) {\n process.env.FIBER_RPC_URL = value;\n explicitFlags.add('rpcUrl');\n }\n break;\n }\n case '--rpc-biscuit-token': {\n const value = getFlagValue(argv, index);\n if (value) {\n process.env.FIBER_RPC_BISCUIT_TOKEN = value;\n explicitFlags.add('rpcBiscuitToken');\n }\n break;\n }\n case '--network': {\n const value = getFlagValue(argv, index);\n if (value) {\n process.env.FIBER_NETWORK = value;\n explicitFlags.add('network');\n }\n break;\n }\n case '--key-password': {\n const value = getFlagValue(argv, index);\n if (value) {\n process.env.FIBER_KEY_PASSWORD = value;\n explicitFlags.add('keyPassword');\n }\n break;\n }\n case '--binary-path': {\n const value = getFlagValue(argv, index);\n if (value) {\n process.env.FIBER_BINARY_PATH = value;\n explicitFlags.add('binaryPath');\n }\n break;\n }\n case '--runtime-proxy-listen':\n case '--proxy-listen': {\n const value = getFlagValue(argv, index);\n if (value) {\n process.env.FIBER_RUNTIME_PROXY_LISTEN = value;\n explicitFlags.add('runtimeProxyListen');\n }\n break;\n }\n default:\n break;\n }\n }\n\n if (!explicitDataDir && profileName) {\n const homeDir = process.env.HOME ?? process.cwd();\n process.env.FIBER_DATA_DIR = join(homeDir, '.fiber-pay', 'profiles', profileName);\n }\n}\n\nfunction printFatal(error: unknown): void {\n const message = error instanceof Error ? error.message : String(error);\n const commanderCode =\n error && typeof error === 'object' && 'code' in error\n ? String((error as { code: unknown }).code)\n : undefined;\n\n if (shouldOutputJson()) {\n printJsonError({\n code: commanderCode ?? 'CLI_FATAL',\n message,\n recoverable: !commanderCode || commanderCode.startsWith('commander.'),\n suggestion: commanderCode?.startsWith('commander.')\n ? 'Run the command with --help and fix invalid arguments.'\n : 'Inspect command arguments and environment, then retry.',\n });\n } else {\n if (commanderCode?.startsWith('commander.')) {\n return;\n }\n console.error('Fatal error:', message);\n }\n}\n\nasync function main(): Promise<void> {\n const argv = process.argv;\n\n if (isTopLevelVersionRequest(argv)) {\n console.log(`${CLI_VERSION} (${CLI_COMMIT})`);\n return;\n }\n\n applyGlobalOverrides(argv);\n const config = getEffectiveConfig(explicitFlags).config;\n\n const program = new Command();\n program\n .name('fiber-pay')\n .description('AI Agent Payment SDK for CKB Lightning Network')\n .option('--profile <name>', 'Use profile at ~/.fiber-pay/profiles/<name>')\n .option('--data-dir <path>', 'Override data directory for all commands')\n .option('--rpc-url <url>', 'Override RPC URL for all commands')\n .option('--rpc-biscuit-token <token>', 'Set RPC Authorization Bearer token for all commands')\n .option('--network <network>', 'Override network for all commands (testnet|mainnet)')\n .option('--key-password <password>', 'Override key password for all commands')\n .option('--binary-path <path>', 'Override fiber binary path for all commands')\n .showHelpAfterError()\n .showSuggestionAfterError();\n\n program.exitOverride();\n program.configureOutput({\n writeOut: (str) => process.stdout.write(str),\n writeErr: (str) => {\n if (!shouldOutputJson()) {\n process.stderr.write(str);\n }\n },\n });\n\n program.addCommand(createNodeCommand(config));\n program.addCommand(createChannelCommand(config));\n program.addCommand(createInvoiceCommand(config));\n program.addCommand(createPaymentCommand(config));\n program.addCommand(createJobCommand(config));\n program.addCommand(createLogsCommand(config));\n program.addCommand(createPeerCommand(config));\n program.addCommand(createGraphCommand(config));\n program.addCommand(createBinaryCommand(config));\n program.addCommand(createConfigCommand(config));\n program.addCommand(createRuntimeCommand(config));\n program.addCommand(createVersionCommand());\n\n await program.parseAsync(argv);\n}\n\nmain().catch((error) => {\n const commanderCode =\n error && typeof error === 'object' && 'code' in error\n ? String((error as { code: unknown }).code)\n : undefined;\n const commanderExitCode =\n error && typeof error === 'object' && 'exitCode' in error\n ? Number((error as { exitCode: unknown }).exitCode)\n : undefined;\n\n printFatal(error);\n\n if (commanderCode?.startsWith('commander.') && commanderExitCode === 0) {\n process.exit(0);\n }\n\n process.exit(1);\n});\n","import { DEFAULT_FIBER_VERSION, type DownloadProgress, downloadFiberBinary } from '@fiber-pay/node';\nimport { Command } from 'commander';\nimport {\n getBinaryDetails,\n getBinaryManagerInstallDirOrThrow,\n resolveBinaryPath,\n} from '../lib/binary-path.js';\nimport type { CliConfig } from '../lib/config.js';\nimport { printJsonError, printJsonSuccess } from '../lib/format.js';\n\nfunction showProgress(progress: DownloadProgress): void {\n const percent = progress.percent !== undefined ? ` (${progress.percent}%)` : '';\n process.stdout.write(`\\r[${progress.phase}]${percent} ${progress.message}`.padEnd(80));\n if (progress.phase === 'installing') {\n console.log();\n }\n}\n\nexport function createBinaryCommand(config: CliConfig): Command {\n const binary = new Command('binary').description('Fiber binary management');\n\n binary\n .command('download')\n .option('--version <version>', 'Fiber binary version', DEFAULT_FIBER_VERSION)\n .option('--force', 'Force re-download')\n .option('--json')\n .action(async (options) => {\n const resolvedBinary = resolveBinaryPath(config);\n let installDir: string;\n try {\n installDir = getBinaryManagerInstallDirOrThrow(resolvedBinary);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (options.json) {\n printJsonError({\n code: 'BINARY_PATH_INCOMPATIBLE',\n message,\n recoverable: true,\n suggestion:\n 'Use `fiber-pay config profile unset binaryPath` or set binaryPath to a standard fnn filename in the target directory.',\n });\n } else {\n console.error(`❌ ${message}`);\n }\n process.exit(1);\n }\n\n const info = await downloadFiberBinary({\n installDir,\n version: options.version,\n force: Boolean(options.force),\n onProgress: options.json ? undefined : showProgress,\n });\n\n if (options.json) {\n printJsonSuccess({\n ...info,\n source: resolvedBinary.source,\n resolvedPath: resolvedBinary.binaryPath,\n });\n } else {\n console.log('\\n✅ Binary installed successfully!');\n console.log(` Path: ${info.path}`);\n console.log(` Version: ${info.version}`);\n console.log(` Ready: ${info.ready ? 'yes' : 'no'}`);\n }\n });\n\n binary\n .command('info')\n .option('--json')\n .action(async (options) => {\n const { resolvedBinary, info } = await getBinaryDetails(config);\n\n if (options.json) {\n printJsonSuccess({\n ...info,\n source: resolvedBinary.source,\n resolvedPath: resolvedBinary.binaryPath,\n });\n } else {\n console.log(info.ready ? '✅ Binary is ready' : '❌ Binary not found or not executable');\n console.log(` Path: ${info.path}`);\n console.log(` Version: ${info.version}`);\n }\n });\n\n return binary;\n}\n","import { dirname, join } from 'node:path';\nimport { type BinaryInfo, BinaryManager, getFiberBinaryInfo } from '@fiber-pay/node';\nimport type { CliConfig } from './config.js';\nimport { getCustomBinaryState } from './node-runtime-daemon.js';\n\nexport interface ResolvedBinaryPath {\n binaryPath: string;\n installDir: string | null;\n managedPath: string;\n managedByBinaryManager: boolean;\n source: 'configured-path' | 'profile-managed';\n}\n\nexport function getProfileBinaryInstallDir(dataDir: string): string {\n return join(dataDir, 'bin');\n}\n\nexport function getProfileManagedBinaryPath(dataDir: string): string {\n return new BinaryManager(getProfileBinaryInstallDir(dataDir)).getBinaryPath();\n}\n\nfunction validateConfiguredBinaryPath(binaryPath: string): string {\n const value = binaryPath.trim();\n if (!value) {\n throw new Error('Configured binaryPath cannot be empty');\n }\n if (value.includes('\\0')) {\n throw new Error('Configured binaryPath contains an invalid null byte');\n }\n return value;\n}\n\nexport function resolveBinaryPath(config: CliConfig): ResolvedBinaryPath {\n const managedPath = getProfileManagedBinaryPath(config.dataDir);\n\n if (config.binaryPath) {\n const binaryPath = validateConfiguredBinaryPath(config.binaryPath);\n const installDir = dirname(binaryPath);\n const expectedPath = new BinaryManager(installDir).getBinaryPath();\n const managedByBinaryManager = expectedPath === binaryPath;\n const source: ResolvedBinaryPath['source'] =\n binaryPath === managedPath ? 'profile-managed' : 'configured-path';\n\n return {\n binaryPath,\n installDir: managedByBinaryManager ? installDir : null,\n managedPath,\n managedByBinaryManager,\n source,\n };\n }\n\n const installDir = getProfileBinaryInstallDir(config.dataDir);\n const binaryPath = managedPath;\n return {\n binaryPath,\n installDir,\n managedPath,\n managedByBinaryManager: true,\n source: 'profile-managed',\n };\n}\n\nexport function getBinaryManagerInstallDirOrThrow(resolvedBinary: ResolvedBinaryPath): string {\n if (resolvedBinary.installDir) {\n return resolvedBinary.installDir;\n }\n\n throw new Error(\n `Configured binaryPath \"${resolvedBinary.binaryPath}\" is incompatible with BinaryManager-managed path naming. ` +\n `BinaryManager expects \"${new BinaryManager(dirname(resolvedBinary.binaryPath)).getBinaryPath()}\". ` +\n 'Set binaryPath to a standard managed name (fnn/fnn.exe) in the target directory, or unset binaryPath to use the profile-managed binary.',\n );\n}\n\nexport async function getBinaryDetails(config: CliConfig): Promise<{\n resolvedBinary: ResolvedBinaryPath;\n info: BinaryInfo | ReturnType<typeof getCustomBinaryState>;\n}> {\n const resolvedBinary = resolveBinaryPath(config);\n const info = resolvedBinary.installDir\n ? await getFiberBinaryInfo(resolvedBinary.installDir)\n : getCustomBinaryState(resolvedBinary.binaryPath);\n\n return { resolvedBinary, info };\n}\n","import { spawnSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\n\nexport function getCustomBinaryState(binaryPath: string): {\n path: string;\n ready: boolean;\n version: string;\n} {\n const exists = existsSync(binaryPath);\n if (!exists) {\n return { path: binaryPath, ready: false, version: 'unknown' };\n }\n\n try {\n const result = spawnSync(binaryPath, ['--version'], { encoding: 'utf-8' });\n if (result.status !== 0) {\n return { path: binaryPath, ready: false, version: 'unknown' };\n }\n const output = `${result.stdout ?? ''}${result.stderr ?? ''}`.trim();\n const firstLine = output.split('\\n').find((line) => line.trim().length > 0) ?? 'unknown';\n return { path: binaryPath, ready: true, version: firstLine.trim() };\n } catch {\n return { path: binaryPath, ready: false, version: 'unknown' };\n }\n}\n\nexport function getBinaryVersion(binaryPath: string): string {\n try {\n const result = spawnSync(binaryPath, ['--version'], { encoding: 'utf-8' });\n if (result.status !== 0) {\n return 'unknown';\n }\n const output = `${result.stdout ?? ''}${result.stderr ?? ''}`.trim();\n if (!output) {\n return 'unknown';\n }\n const firstLine = output.split('\\n').find((line) => line.trim().length > 0);\n return firstLine?.trim() ?? 'unknown';\n } catch {\n return 'unknown';\n }\n}\n\nfunction getCliEntrypoint(): string {\n const entrypoint = process.argv[1];\n if (!entrypoint) {\n throw new Error('Unable to resolve CLI entrypoint path');\n }\n return entrypoint;\n}\n\nexport function startRuntimeDaemonFromNode(params: {\n dataDir: string;\n rpcUrl: string;\n proxyListen: string;\n stateFilePath: string;\n alertLogsBaseDir: string;\n}): { ok: true } | { ok: false; message: string } {\n const cliEntrypoint = getCliEntrypoint();\n const result = spawnSync(\n process.execPath,\n [\n cliEntrypoint,\n '--data-dir',\n params.dataDir,\n '--rpc-url',\n params.rpcUrl,\n 'runtime',\n 'start',\n '--daemon',\n '--fiber-rpc-url',\n params.rpcUrl,\n '--proxy-listen',\n params.proxyListen,\n '--state-file',\n params.stateFilePath,\n '--alert-logs-base-dir',\n params.alertLogsBaseDir,\n '--json',\n ],\n { encoding: 'utf-8' },\n );\n\n if (result.status === 0) {\n return { ok: true };\n }\n\n const stderr = (result.stderr ?? '').trim();\n const stdout = (result.stdout ?? '').trim();\n const details = stderr || stdout || `exit code ${result.status ?? 'unknown'}`;\n return { ok: false, message: details };\n}\n\nexport function stopRuntimeDaemonFromNode(params: { dataDir: string; rpcUrl: string }): void {\n const cliEntrypoint = getCliEntrypoint();\n spawnSync(\n process.execPath,\n [\n cliEntrypoint,\n '--data-dir',\n params.dataDir,\n '--rpc-url',\n params.rpcUrl,\n 'runtime',\n 'stop',\n '--json',\n ],\n { encoding: 'utf-8' },\n );\n}\n","import {\n type Channel,\n ChannelState,\n type CkbInvoice,\n type GetPaymentResult,\n shannonsToCkb,\n toHex,\n} from '@fiber-pay/sdk';\n\nexport function truncateMiddle(value: string, start = 10, end = 8): string {\n if (!value || value.length <= start + end + 3) {\n return value;\n }\n return `${value.slice(0, start)}...${value.slice(-end)}`;\n}\n\nexport function parseHexTimestampMs(hexTimestamp: string): number | null {\n if (!hexTimestamp) return null;\n try {\n const raw = Number(BigInt(hexTimestamp));\n if (!Number.isFinite(raw) || raw <= 0) return null;\n return raw > 1_000_000_000_000 ? raw : raw * 1000;\n } catch {\n return null;\n }\n}\n\nexport function formatAge(whenMs: number | null): string {\n if (!whenMs) return 'unknown';\n const diff = Date.now() - whenMs;\n if (diff < 0) return 'just now';\n\n const seconds = Math.floor(diff / 1000);\n if (seconds < 60) return `${seconds}s ago`;\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ${minutes % 60}m ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ${hours % 24}h ago`;\n}\n\nexport function stateLabel(state: ChannelState): string {\n switch (state) {\n case ChannelState.NegotiatingFunding:\n return '🔄 Negotiating Funding';\n case ChannelState.CollaboratingFundingTx:\n return '🧩 Collaborating Funding Tx';\n case ChannelState.SigningCommitment:\n return '✍️ Signing Commitment';\n case ChannelState.AwaitingTxSignatures:\n return '⏳ Awaiting Tx Signatures';\n case ChannelState.AwaitingChannelReady:\n return '⏳ Awaiting Channel Ready';\n case ChannelState.ChannelReady:\n return '✅ Channel Ready';\n case ChannelState.ShuttingDown:\n return '🛑 Shutting Down';\n case ChannelState.Closed:\n return '❌ Closed';\n default:\n return state;\n }\n}\n\nexport function parseChannelState(input: string | undefined): ChannelState | undefined {\n if (!input) return undefined;\n const trimmed = input.trim();\n const legacy = trimmed.toUpperCase();\n const normalizedInput = trimmed.replace(/[^a-zA-Z0-9]/g, '').toLowerCase();\n\n const legacyMap: Record<string, ChannelState> = {\n NEGOTIATING_FUNDING: ChannelState.NegotiatingFunding,\n COLLABORATING_FUNDING_TX: ChannelState.CollaboratingFundingTx,\n SIGNING_COMMITMENT: ChannelState.SigningCommitment,\n AWAITING_TX_SIGNATURES: ChannelState.AwaitingTxSignatures,\n AWAITING_CHANNEL_READY: ChannelState.AwaitingChannelReady,\n CHANNEL_READY: ChannelState.ChannelReady,\n SHUTTING_DOWN: ChannelState.ShuttingDown,\n CLOSED: ChannelState.Closed,\n };\n\n if (legacy in legacyMap) return legacyMap[legacy];\n\n for (const value of Object.values(ChannelState)) {\n const normalizedValue = value.replace(/[^a-zA-Z0-9]/g, '').toLowerCase();\n if (normalizedValue === normalizedInput) return value;\n }\n\n return undefined;\n}\n\nexport function formatChannel(channel: Channel): Record<string, unknown> {\n const local = BigInt(channel.local_balance);\n const remote = BigInt(channel.remote_balance);\n const capacity = local + remote;\n const localPct = capacity > 0n ? Number((local * 100n) / capacity) : 0;\n const remotePct = capacity > 0n ? 100 - localPct : 0;\n\n return {\n channelId: channel.channel_id,\n channelIdShort: truncateMiddle(channel.channel_id, 10, 8),\n peerId: channel.peer_id,\n peerIdShort: truncateMiddle(channel.peer_id, 10, 8),\n state: channel.state.state_name,\n stateLabel: stateLabel(channel.state.state_name),\n stateFlags: channel.state.state_flags,\n localBalanceCkb: shannonsToCkb(channel.local_balance),\n remoteBalanceCkb: shannonsToCkb(channel.remote_balance),\n capacityCkb: shannonsToCkb(toHex(capacity)),\n balanceRatio: `${localPct}/${remotePct}`,\n pendingTlcs: channel.pending_tlcs.length,\n enabled: channel.enabled,\n isPublic: channel.is_public,\n age: formatAge(parseHexTimestampMs(channel.created_at)),\n };\n}\n\nexport function getChannelSummary(channels: Channel[]): Record<string, unknown> {\n let totalLocal = 0n;\n let totalRemote = 0n;\n let active = 0;\n\n for (const channel of channels) {\n totalLocal += BigInt(channel.local_balance);\n totalRemote += BigInt(channel.remote_balance || '0x0');\n if (channel.state.state_name === ChannelState.ChannelReady) {\n active++;\n }\n }\n\n return {\n count: channels.length,\n activeCount: active,\n totalLocalCkb: shannonsToCkb(toHex(totalLocal)),\n totalRemoteCkb: shannonsToCkb(toHex(totalRemote)),\n totalCapacityCkb: shannonsToCkb(toHex(totalLocal + totalRemote)),\n };\n}\n\nexport function extractInvoiceMetadata(invoice: CkbInvoice): {\n description?: string;\n expirySeconds?: number;\n expiresAt?: string;\n age: string;\n} {\n let description: string | undefined;\n let expirySeconds: number | undefined;\n\n for (const attr of invoice.data.attrs) {\n if ('Description' in attr) description = attr.Description;\n if ('ExpiryTime' in attr) {\n try {\n expirySeconds = Number(BigInt(attr.ExpiryTime));\n } catch {\n // ignore malformed expiry field\n }\n }\n }\n\n const createdMs = parseHexTimestampMs(invoice.data.timestamp);\n const expiresAt =\n createdMs && expirySeconds\n ? new Date(createdMs + expirySeconds * 1000).toISOString()\n : undefined;\n\n return {\n description,\n expirySeconds,\n expiresAt,\n age: formatAge(createdMs),\n };\n}\n\nexport function formatPaymentResult(payment: GetPaymentResult): Record<string, unknown> {\n const createdAtMs = parseHexTimestampMs(payment.created_at);\n const updatedAtMs = parseHexTimestampMs(payment.last_updated_at);\n\n return {\n paymentHash: payment.payment_hash,\n status: payment.status,\n feeCkb: shannonsToCkb(payment.fee),\n failureReason: payment.failed_error,\n createdAt: createdAtMs ? new Date(createdAtMs).toISOString() : payment.created_at,\n updatedAt: updatedAtMs ? new Date(updatedAtMs).toISOString() : payment.last_updated_at,\n routeCount: payment.routers?.length ?? 0,\n routers: payment.routers,\n };\n}\n\nexport function hasJsonFlag(args: string[]): boolean {\n return args.includes('--json');\n}\n\nexport function printJson(payload: unknown): void {\n console.log(JSON.stringify(payload, null, 2));\n}\n\nexport interface CliErrorPayload {\n code: string;\n message: string;\n recoverable?: boolean;\n suggestion?: string;\n details?: unknown;\n}\n\nexport function printJsonSuccess(data: unknown): void {\n printJson({ success: true, data });\n}\n\nexport function printJsonError(error: CliErrorPayload): void {\n printJson({ success: false, error });\n}\n\nexport function printJsonEvent(event: string, data: unknown, ts = new Date().toISOString()): void {\n process.stdout.write(`${JSON.stringify({ event, ts, data })}\\n`);\n}\n\nexport function printChannelDetailHuman(channel: Channel): void {\n const local = shannonsToCkb(channel.local_balance);\n const remote = shannonsToCkb(channel.remote_balance);\n const capacity = local + remote;\n\n console.log('Channel');\n console.log(` ID: ${channel.channel_id}`);\n console.log(` Peer: ${channel.peer_id}`);\n console.log(\n ` State: ${stateLabel(channel.state.state_name)} (${channel.state.state_name})`,\n );\n console.log(` Enabled: ${channel.enabled ? 'yes' : 'no'}`);\n console.log(` Public: ${channel.is_public ? 'yes' : 'no'}`);\n console.log(\n ` Balance: local ${local} CKB | remote ${remote} CKB | capacity ${capacity} CKB`,\n );\n console.log(` Pending TLCs: ${channel.pending_tlcs.length}`);\n console.log(` Age: ${formatAge(parseHexTimestampMs(channel.created_at))}`);\n console.log(\n ` Outpoint: ${channel.channel_outpoint ? `${channel.channel_outpoint.tx_hash}:${channel.channel_outpoint.index}` : 'n/a'}`,\n );\n console.log(` Commitment Tx: ${channel.latest_commitment_transaction_hash ?? 'n/a'}`);\n console.log(` Shutdown Tx: ${channel.shutdown_transaction_hash ?? 'n/a'}`);\n}\n\nexport function printInvoiceDetailHuman(data: {\n paymentHash: string;\n status: string;\n invoice: string;\n amountCkb?: number;\n currency: string;\n description?: string;\n createdAt: string;\n expiresAt?: string;\n age: string;\n}): void {\n console.log('Invoice');\n console.log(` Payment Hash: ${data.paymentHash}`);\n console.log(` Status: ${data.status}`);\n console.log(\n ` Amount: ${data.amountCkb ?? 'n/a'} ${data.amountCkb !== undefined ? 'CKB' : ''}`.trim(),\n );\n console.log(` Currency: ${data.currency}`);\n console.log(` Description: ${data.description ?? 'n/a'}`);\n console.log(` Created At: ${data.createdAt}`);\n console.log(` Expires At: ${data.expiresAt ?? 'n/a'}`);\n console.log(` Age: ${data.age}`);\n console.log(` Invoice: ${data.invoice}`);\n}\n\nexport function printPaymentDetailHuman(payment: GetPaymentResult): void {\n const createdAtMs = parseHexTimestampMs(payment.created_at);\n const updatedAtMs = parseHexTimestampMs(payment.last_updated_at);\n\n console.log('Payment');\n console.log(` Hash: ${payment.payment_hash}`);\n console.log(` Status: ${payment.status}`);\n console.log(` Fee: ${shannonsToCkb(payment.fee)} CKB`);\n console.log(` Failure: ${payment.failed_error ?? 'n/a'}`);\n console.log(\n ` Created At: ${createdAtMs ? new Date(createdAtMs).toISOString() : payment.created_at}`,\n );\n console.log(\n ` Updated At: ${updatedAtMs ? new Date(updatedAtMs).toISOString() : payment.last_updated_at}`,\n );\n const routers = payment.routers ?? [];\n console.log(` Routes: ${routers.length}`);\n if (routers.length > 0) {\n for (let i = 0; i < routers.length; i++) {\n const hops = routers[i].nodes.map((node) => truncateMiddle(node.pubkey, 8, 8)).join(' -> ');\n console.log(` #${i + 1}: ${hops}`);\n }\n }\n}\n\nexport function printChannelListHuman(channels: Channel[]): void {\n if (channels.length === 0) {\n console.log('No channels found.');\n return;\n }\n\n const summary = getChannelSummary(channels) as {\n count: number;\n activeCount: number;\n totalLocalCkb: number;\n totalRemoteCkb: number;\n totalCapacityCkb: number;\n };\n\n console.log(`Channels: ${summary.count} total, ${summary.activeCount} ready`);\n console.log(\n `Liquidity: local ${summary.totalLocalCkb} CKB | remote ${summary.totalRemoteCkb} CKB | capacity ${summary.totalCapacityCkb} CKB`,\n );\n console.log('');\n console.log(\n 'ID PEER STATE LOCAL REMOTE TLC',\n );\n console.log(\n '---------------------------------------------------------------------------------------------------',\n );\n\n for (const channel of channels) {\n const id = truncateMiddle(channel.channel_id, 10, 8).padEnd(22, ' ');\n const peer = truncateMiddle(channel.peer_id, 10, 8).padEnd(22, ' ');\n const state = channel.state.state_name.padEnd(24, ' ');\n const local = `${shannonsToCkb(channel.local_balance)}`.padStart(8, ' ');\n const remote = `${shannonsToCkb(channel.remote_balance)}`.padStart(8, ' ');\n const tlcs = `${channel.pending_tlcs.length}`.padStart(4, ' ');\n console.log(`${id} ${peer} ${state} ${local} ${remote} ${tlcs}`);\n }\n}\n\nexport function printBalanceHuman(data: {\n totalCkb: number;\n channelLocalCkb?: number;\n fundingAddress?: string;\n fundingAddressTotalCkb?: number;\n availableToSend: number;\n availableToReceive: number;\n channelCount: number;\n activeChannelCount: number;\n fundingBalanceError?: string;\n}): void {\n console.log('Balance');\n console.log(` Total: ${data.totalCkb} CKB`);\n if (data.channelLocalCkb !== undefined) {\n console.log(` In Channels (Local): ${data.channelLocalCkb} CKB`);\n }\n console.log(` Available To Send: ${data.availableToSend} CKB`);\n console.log(` Available To Receive: ${data.availableToReceive} CKB`);\n console.log(\n ` Channels: ${data.channelCount} total (${data.activeChannelCount} active)`,\n );\n if (data.fundingAddressTotalCkb !== undefined) {\n console.log(` Funding Address: ${data.fundingAddressTotalCkb} CKB`);\n }\n if (data.fundingAddress) {\n console.log(` Funding Lock Addr: ${data.fundingAddress}`);\n }\n if (data.fundingBalanceError) {\n console.log(` Funding Balance Note: ${data.fundingBalanceError}`);\n }\n}\n\nexport function printPeerListHuman(\n peers: Array<{ peer_id: string; pubkey: string; address: string }>,\n): void {\n if (peers.length === 0) {\n console.log('No connected peers.');\n return;\n }\n\n console.log(`Peers: ${peers.length}`);\n console.log('');\n console.log('PEER ID PUBKEY ADDRESS');\n console.log('--------------------------------------------------------------------------');\n for (const peer of peers) {\n const peerId = truncateMiddle(peer.peer_id, 10, 8).padEnd(22, ' ');\n const pubkey = truncateMiddle(peer.pubkey, 10, 8).padEnd(22, ' ');\n console.log(`${peerId} ${pubkey} ${peer.address}`);\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport { type ChannelState, ckbToShannons, type HexString } from '@fiber-pay/sdk';\nimport { Command } from 'commander';\nimport { sleep } from '../lib/async.js';\nimport type { CliConfig } from '../lib/config.js';\nimport {\n formatChannel,\n getChannelSummary,\n parseChannelState,\n printChannelDetailHuman,\n printChannelListHuman,\n printJsonError,\n printJsonEvent,\n printJsonSuccess,\n truncateMiddle,\n} from '../lib/format.js';\nimport { createReadyRpcClient, resolveRpcEndpoint } from '../lib/rpc.js';\nimport { tryCreateRuntimeChannelJob } from '../lib/runtime-jobs.js';\nimport { registerChannelRebalanceCommand } from './rebalance.js';\n\nexport function createChannelCommand(config: CliConfig): Command {\n const channel = new Command('channel').description('Channel lifecycle and status commands');\n\n channel\n .command('list')\n .option('--state <state>')\n .option('--peer <peerId>')\n .option('--include-closed')\n .option('--raw')\n .option('--json')\n .action(async (options) => {\n const rpc = await createReadyRpcClient(config);\n const stateFilter = parseChannelState(options.state);\n const response = await rpc.listChannels(\n options.peer\n ? { peer_id: options.peer, include_closed: Boolean(options.includeClosed) }\n : { include_closed: Boolean(options.includeClosed) },\n );\n const channels = stateFilter\n ? response.channels.filter((item) => item.state.state_name === stateFilter)\n : response.channels;\n\n if (options.raw || options.json) {\n printJsonSuccess({ channels, count: channels.length });\n } else {\n printChannelListHuman(channels);\n }\n });\n\n channel\n .command('get')\n .argument('<channelId>')\n .option('--raw')\n .option('--json')\n .action(async (channelId, options) => {\n const rpc = await createReadyRpcClient(config);\n const response = await rpc.listChannels({ include_closed: true });\n const found = response.channels.find((item) => item.channel_id === channelId);\n if (!found) {\n if (options.json) {\n printJsonError({\n code: 'CHANNEL_NOT_FOUND',\n message: `Channel not found: ${channelId}`,\n recoverable: true,\n suggestion: 'List channels first and retry with a valid channel id.',\n details: { channelId },\n });\n } else {\n console.error(`Error: Channel not found: ${channelId}`);\n }\n process.exit(1);\n }\n\n if (options.raw || options.json) {\n printJsonSuccess(found);\n } else {\n printChannelDetailHuman(found);\n }\n });\n\n channel\n .command('watch')\n .option('--interval <seconds>', 'Refresh interval', '5')\n .option('--timeout <seconds>')\n .option('--on-timeout <behavior>', 'fail | success', 'fail')\n .option('--channel <channelId>')\n .option('--peer <peerId>')\n .option('--state <state>')\n .option('--until <state>')\n .option('--include-closed')\n .option('--no-clear')\n .option('--json')\n .action(async (options) => {\n const intervalSeconds = parseInt(options.interval, 10);\n const timeoutSeconds = options.timeout ? parseInt(options.timeout, 10) : undefined;\n const onTimeout = String(options.onTimeout ?? 'fail')\n .trim()\n .toLowerCase();\n const stateFilter = parseChannelState(options.state);\n const untilState = parseChannelState(options.until);\n const noClear = Boolean(options.noClear);\n const json = Boolean(options.json);\n if (!['fail', 'success'].includes(onTimeout)) {\n if (json) {\n printJsonError({\n code: 'CHANNEL_WATCH_INPUT_INVALID',\n message: `Invalid --on-timeout value: ${options.onTimeout}. Expected fail or success`,\n recoverable: true,\n suggestion: 'Use `--on-timeout fail` or `--on-timeout success`.',\n details: { provided: options.onTimeout, expected: ['fail', 'success'] },\n });\n } else {\n console.error(\n `Error: Invalid --on-timeout value: ${options.onTimeout}. Expected fail or success`,\n );\n }\n process.exit(1);\n }\n const rpc = await createReadyRpcClient(config);\n const startedAt = Date.now();\n const previousStates = new Map<string, ChannelState>();\n\n while (true) {\n const response = await rpc.listChannels(\n options.peer\n ? { peer_id: options.peer, include_closed: Boolean(options.includeClosed) }\n : { include_closed: Boolean(options.includeClosed) },\n );\n let channels = response.channels;\n\n if (options.channel) {\n channels = channels.filter((item) => item.channel_id === options.channel);\n }\n if (stateFilter) {\n channels = channels.filter((item) => item.state.state_name === stateFilter);\n }\n\n const stateChanges: Array<{ channelId: string; from: ChannelState; to: ChannelState }> = [];\n for (const ch of channels) {\n const prev = previousStates.get(ch.channel_id);\n if (prev && prev !== ch.state.state_name) {\n stateChanges.push({ channelId: ch.channel_id, from: prev, to: ch.state.state_name });\n }\n previousStates.set(ch.channel_id, ch.state.state_name);\n }\n\n if (json) {\n printJsonEvent('snapshot', {\n channels: channels.map(formatChannel),\n summary: getChannelSummary(channels),\n });\n\n for (const change of stateChanges) {\n printJsonEvent('state_change', {\n channelId: change.channelId,\n from: change.from,\n to: change.to,\n });\n }\n } else {\n if (!noClear) {\n console.clear();\n }\n\n console.log(`⏱️ Channel monitor - ${new Date().toISOString()}`);\n console.log(\n ` Refresh: ${intervalSeconds}s${timeoutSeconds ? ` | Timeout: ${timeoutSeconds}s` : ''}${untilState ? ` | Until: ${untilState}` : ''}`,\n );\n\n if (stateChanges.length > 0) {\n console.log('\\n🔔 State changes:');\n for (const change of stateChanges) {\n console.log(` ${truncateMiddle(change.channelId)}: ${change.from} -> ${change.to}`);\n }\n }\n\n printChannelListHuman(channels);\n }\n\n if (untilState && channels.some((item) => item.state.state_name === untilState)) {\n if (json) {\n printJsonEvent('terminal', { reason: 'target_state_reached', untilState });\n } else {\n console.log(`\\n✅ Target state reached: ${untilState}`);\n }\n return;\n }\n\n if (timeoutSeconds !== undefined && Date.now() - startedAt >= timeoutSeconds * 1000) {\n if (onTimeout === 'success') {\n if (json) {\n printJsonEvent('terminal', {\n reason: 'timeout',\n timeoutSeconds,\n });\n } else {\n console.log('\\n⏰ Monitor timeout reached (treated as success).');\n }\n return;\n }\n\n if (json) {\n printJsonError({\n code: 'CHANNEL_WATCH_TIMEOUT',\n message: `Channel monitor timed out after ${timeoutSeconds}s`,\n recoverable: true,\n suggestion: 'Increase timeout or continue monitoring with another watch run.',\n details: { timeoutSeconds },\n });\n process.exit(1);\n }\n console.log('\\n⏰ Monitor timeout reached.');\n return;\n }\n\n await sleep(intervalSeconds * 1000);\n }\n });\n\n channel\n .command('open')\n .requiredOption('--peer <peerIdOrMultiaddr>')\n .requiredOption('--funding <ckb>')\n .option('--private')\n .option(\n '--idempotency-key <key>',\n 'Reuse this key only when retrying the exact same open intent',\n )\n .option('--json')\n .action(async (options) => {\n const rpc = await createReadyRpcClient(config);\n const json = Boolean(options.json);\n const peerInput = options.peer as string;\n const fundingCkb = parseFloat(options.funding);\n\n let peerId = peerInput;\n if (peerInput.includes('/')) {\n await rpc.connectPeer({ address: peerInput });\n const peerIdMatch = peerInput.match(/\\/p2p\\/([^/]+)/);\n if (peerIdMatch) peerId = peerIdMatch[1];\n }\n\n const idempotencyKey =\n typeof options.idempotencyKey === 'string' && options.idempotencyKey.trim().length > 0\n ? options.idempotencyKey.trim()\n : `open:${peerId}:${randomUUID()}`;\n\n const endpoint = resolveRpcEndpoint(config);\n if (endpoint.target === 'runtime-proxy') {\n const created = await tryCreateRuntimeChannelJob(endpoint.url, {\n params: {\n action: 'open',\n peerId,\n openChannelParams: {\n peer_id: peerId,\n funding_amount: ckbToShannons(fundingCkb),\n public: !options.private,\n },\n waitForReady: false,\n },\n options: {\n idempotencyKey,\n reuseTerminal: false,\n },\n });\n\n if (created) {\n const payload = {\n jobId: created.id,\n jobState: created.state,\n peer: peerId,\n fundingCkb,\n idempotencyKey,\n };\n\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log('Channel open job submitted');\n console.log(` Job: ${payload.jobId}`);\n console.log(` Job State: ${payload.jobState}`);\n console.log(` Peer: ${payload.peer}`);\n console.log(` Funding: ${payload.fundingCkb} CKB`);\n console.log(` Idempotency Key: ${payload.idempotencyKey}`);\n }\n return;\n }\n }\n\n const result = await rpc.openChannel({\n peer_id: peerId,\n funding_amount: ckbToShannons(fundingCkb),\n public: !options.private,\n });\n\n const payload = { temporaryChannelId: result.temporary_channel_id, peer: peerId, fundingCkb };\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log('Channel open initiated');\n console.log(` Temporary Channel ID: ${payload.temporaryChannelId}`);\n console.log(` Peer: ${payload.peer}`);\n console.log(` Funding: ${payload.fundingCkb} CKB`);\n }\n });\n\n channel\n .command('accept')\n .argument('<temporaryChannelId>')\n .requiredOption('--funding <ckb>')\n .option('--json')\n .action(async (temporaryChannelId, options) => {\n const rpc = await createReadyRpcClient(config);\n const json = Boolean(options.json);\n const fundingCkb = parseFloat(options.funding);\n\n const endpoint = resolveRpcEndpoint(config);\n if (endpoint.target === 'runtime-proxy') {\n const created = await tryCreateRuntimeChannelJob(endpoint.url, {\n params: {\n action: 'accept',\n acceptChannelParams: {\n temporary_channel_id: temporaryChannelId as HexString,\n funding_amount: ckbToShannons(fundingCkb),\n },\n },\n options: {\n idempotencyKey: `accept:temporary:${temporaryChannelId}`,\n },\n });\n\n if (created) {\n const payload = {\n jobId: created.id,\n jobState: created.state,\n temporaryChannelId,\n fundingCkb,\n };\n\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log('Channel accept job submitted');\n console.log(` Job: ${payload.jobId}`);\n console.log(` Job State: ${payload.jobState}`);\n console.log(` Temporary Channel ID: ${payload.temporaryChannelId}`);\n console.log(` Funding: ${payload.fundingCkb} CKB`);\n }\n return;\n }\n }\n\n const result = await rpc.acceptChannel({\n temporary_channel_id: temporaryChannelId as HexString,\n funding_amount: ckbToShannons(fundingCkb),\n });\n\n const payload = { channelId: result.channel_id, temporaryChannelId, fundingCkb };\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log('Channel accepted');\n console.log(` Channel ID: ${payload.channelId}`);\n console.log(` Temporary Channel ID: ${payload.temporaryChannelId}`);\n console.log(` Funding: ${payload.fundingCkb} CKB`);\n }\n });\n\n channel\n .command('close')\n .argument('<channelId>')\n .option('--force')\n .option('--json')\n .action(async (channelId, options) => {\n const rpc = await createReadyRpcClient(config);\n const json = Boolean(options.json);\n\n const endpoint = resolveRpcEndpoint(config);\n if (endpoint.target === 'runtime-proxy') {\n const created = await tryCreateRuntimeChannelJob(endpoint.url, {\n params: {\n action: 'shutdown',\n channelId: channelId as HexString,\n shutdownChannelParams: {\n channel_id: channelId as HexString,\n force: Boolean(options.force),\n },\n waitForClosed: Boolean(options.force),\n },\n options: {\n idempotencyKey: `shutdown:channel:${channelId}`,\n },\n });\n\n if (created) {\n const payload = {\n jobId: created.id,\n jobState: created.state,\n channelId,\n force: Boolean(options.force),\n message: options.force\n ? 'Channel force close job submitted'\n : 'Channel close job submitted',\n };\n\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log(payload.message);\n console.log(` Job: ${payload.jobId}`);\n console.log(` Job State: ${payload.jobState}`);\n console.log(` Channel ID: ${payload.channelId}`);\n }\n return;\n }\n }\n\n await rpc.shutdownChannel({\n channel_id: channelId as HexString,\n force: Boolean(options.force),\n });\n const payload = {\n channelId,\n force: Boolean(options.force),\n message: options.force ? 'Channel force close initiated' : 'Channel close initiated',\n };\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log(payload.message);\n console.log(` Channel ID: ${payload.channelId}`);\n }\n });\n\n channel\n .command('abandon')\n .argument('<channelId>')\n .option('--json')\n .action(async (channelId, options) => {\n const rpc = await createReadyRpcClient(config);\n const json = Boolean(options.json);\n\n const endpoint = resolveRpcEndpoint(config);\n if (endpoint.target === 'runtime-proxy') {\n const created = await tryCreateRuntimeChannelJob(endpoint.url, {\n params: {\n action: 'abandon',\n channelId: channelId as HexString,\n abandonChannelParams: {\n channel_id: channelId as HexString,\n },\n },\n options: {\n idempotencyKey: `abandon:channel:${channelId}`,\n },\n });\n\n if (created) {\n const payload = {\n jobId: created.id,\n jobState: created.state,\n channelId,\n message: 'Channel abandon job submitted.',\n };\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log(payload.message);\n console.log(` Job: ${payload.jobId}`);\n console.log(` Job State: ${payload.jobState}`);\n console.log(` Channel ID: ${payload.channelId}`);\n }\n return;\n }\n }\n\n await rpc.abandonChannel({ channel_id: channelId as HexString });\n const payload = { channelId, message: 'Channel abandoned.' };\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log(payload.message);\n console.log(` Channel ID: ${payload.channelId}`);\n }\n });\n\n registerChannelRebalanceCommand(channel, config);\n\n channel\n .command('update')\n .argument('<channelId>')\n .option('--enabled <enabled>')\n .option('--tlc-expiry-delta <ms>')\n .option('--tlc-minimum-value <shannonsHex>')\n .option('--tlc-fee-proportional-millionths <value>')\n .option('--json')\n .action(async (channelId, options) => {\n const rpc = await createReadyRpcClient(config);\n const json = Boolean(options.json);\n const updateParams = {\n channel_id: channelId as HexString,\n enabled: options.enabled !== undefined ? options.enabled === 'true' : undefined,\n tlc_expiry_delta: options.tlcExpiryDelta,\n tlc_minimum_value: options.tlcMinimumValue,\n tlc_fee_proportional_millionths: options.tlcFeeProportionalMillionths,\n };\n\n const endpoint = resolveRpcEndpoint(config);\n if (endpoint.target === 'runtime-proxy') {\n const created = await tryCreateRuntimeChannelJob(endpoint.url, {\n params: {\n action: 'update',\n channelId: channelId as HexString,\n updateChannelParams: updateParams,\n },\n options: {\n reuseTerminal: false,\n },\n });\n\n if (created) {\n const payload = {\n jobId: created.id,\n jobState: created.state,\n channelId,\n message: 'Channel update job submitted.',\n };\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log(payload.message);\n console.log(` Job: ${payload.jobId}`);\n console.log(` Job State: ${payload.jobState}`);\n console.log(` Channel ID: ${payload.channelId}`);\n }\n return;\n }\n }\n\n await rpc.updateChannel(updateParams);\n const payload = { channelId, message: 'Channel updated.' };\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log(payload.message);\n console.log(` Channel ID: ${payload.channelId}`);\n }\n });\n\n return channel;\n}\n","export function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import { FiberRpcClient } from '@fiber-pay/sdk';\nimport type { CliConfig } from './config.js';\nimport { isProcessRunning } from './pid.js';\nimport { readRuntimeMeta, readRuntimePid } from './runtime-meta.js';\n\nexport type ResolvedRpcTarget = 'node-rpc' | 'runtime-proxy';\n\nexport interface ResolvedRpcEndpoint {\n url: string;\n target: ResolvedRpcTarget;\n}\n\nfunction normalizeUrl(url: string): string {\n try {\n const normalized = new URL(url).toString();\n return normalized.endsWith('/') ? normalized.slice(0, -1) : normalized;\n } catch {\n return url.endsWith('/') ? url.slice(0, -1) : url;\n }\n}\n\nfunction resolveRuntimeProxyUrl(config: CliConfig): string | undefined {\n const runtimeMeta = readRuntimeMeta(config.dataDir);\n const runtimePid = readRuntimePid(config.dataDir);\n\n if (!runtimeMeta || !runtimePid || !isProcessRunning(runtimePid)) {\n return undefined;\n }\n\n if (!runtimeMeta.proxyListen || !runtimeMeta.fiberRpcUrl) {\n return undefined;\n }\n\n if (normalizeUrl(runtimeMeta.fiberRpcUrl) !== normalizeUrl(config.rpcUrl)) {\n return undefined;\n }\n\n if (\n runtimeMeta.proxyListen.startsWith('http://') ||\n runtimeMeta.proxyListen.startsWith('https://')\n ) {\n return runtimeMeta.proxyListen;\n }\n\n return `http://${runtimeMeta.proxyListen}`;\n}\n\nexport function createRpcClient(config: CliConfig): FiberRpcClient {\n const resolved = resolveRpcEndpoint(config);\n return new FiberRpcClient({\n url: resolved.url,\n biscuitToken: config.rpcBiscuitToken,\n });\n}\n\nexport function resolveRpcEndpoint(config: CliConfig): ResolvedRpcEndpoint {\n const runtimeProxyUrl = resolveRuntimeProxyUrl(config);\n if (runtimeProxyUrl) {\n return {\n url: runtimeProxyUrl,\n target: 'runtime-proxy',\n };\n }\n\n return {\n url: config.rpcUrl,\n target: 'node-rpc',\n };\n}\n\nexport async function createReadyRpcClient(\n config: CliConfig,\n options: { timeout?: number; interval?: number } = {},\n): Promise<FiberRpcClient> {\n const rpc = createRpcClient(config);\n await rpc.waitForReady({ timeout: options.timeout ?? 3000, interval: options.interval ?? 500 });\n return rpc;\n}\n","import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\nexport function getPidFilePath(dataDir: string): string {\n return join(dataDir, 'fiber.pid');\n}\n\nexport function writePidFile(dataDir: string, pid: number): void {\n writeFileSync(getPidFilePath(dataDir), String(pid));\n}\n\nexport function readPidFile(dataDir: string): number | null {\n const pidPath = getPidFilePath(dataDir);\n if (!existsSync(pidPath)) return null;\n\n try {\n return parseInt(readFileSync(pidPath, 'utf-8').trim(), 10);\n } catch {\n return null;\n }\n}\n\nexport function removePidFile(dataDir: string): void {\n const pidPath = getPidFilePath(dataDir);\n if (existsSync(pidPath)) {\n unlinkSync(pidPath);\n }\n}\n\nexport function isProcessRunning(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n","import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\nexport interface RuntimeMeta {\n pid: number;\n startedAt: string;\n fiberRpcUrl: string;\n proxyListen: string;\n stateFilePath?: string;\n alertLogFilePath?: string;\n fnnStdoutLogPath?: string;\n fnnStderrLogPath?: string;\n /** Base logs directory for discovering daily log directories. */\n logsBaseDir?: string;\n daemon: boolean;\n}\n\nexport function getRuntimePidFilePath(dataDir: string): string {\n return join(dataDir, 'runtime.pid');\n}\n\nexport function getRuntimeMetaFilePath(dataDir: string): string {\n return join(dataDir, 'runtime.meta.json');\n}\n\nexport function writeRuntimePid(dataDir: string, pid: number): void {\n writeFileSync(getRuntimePidFilePath(dataDir), String(pid));\n}\n\nexport function readRuntimePid(dataDir: string): number | null {\n const pidPath = getRuntimePidFilePath(dataDir);\n if (!existsSync(pidPath)) return null;\n try {\n return Number.parseInt(readFileSync(pidPath, 'utf-8').trim(), 10);\n } catch {\n return null;\n }\n}\n\nexport function writeRuntimeMeta(dataDir: string, meta: RuntimeMeta): void {\n writeFileSync(getRuntimeMetaFilePath(dataDir), JSON.stringify(meta, null, 2));\n}\n\nexport function readRuntimeMeta(dataDir: string): RuntimeMeta | null {\n const metaPath = getRuntimeMetaFilePath(dataDir);\n if (!existsSync(metaPath)) return null;\n try {\n return JSON.parse(readFileSync(metaPath, 'utf-8')) as RuntimeMeta;\n } catch {\n return null;\n }\n}\n\nexport function removeRuntimeFiles(dataDir: string): void {\n const pidPath = getRuntimePidFilePath(dataDir);\n const metaPath = getRuntimeMetaFilePath(dataDir);\n if (existsSync(pidPath)) {\n unlinkSync(pidPath);\n }\n if (existsSync(metaPath)) {\n unlinkSync(metaPath);\n }\n}\n","import { sleep } from './async.js';\n\nexport type RuntimeJobRecord = {\n id: string;\n type?: string;\n state: string;\n params?: Record<string, unknown>;\n idempotencyKey?: string;\n retryCount?: number;\n maxRetries?: number;\n createdAt?: number;\n updatedAt?: number;\n completedAt?: number;\n result?:\n | {\n paymentHash?: string;\n fee?: string;\n failedError?: string;\n }\n | Record<string, unknown>;\n error?: { message?: string };\n};\n\nexport type RuntimeJobEventRecord = {\n id: string;\n eventType: string;\n fromState?: string;\n toState?: string;\n createdAt: number;\n data?: unknown;\n};\n\nexport type RuntimePaymentJobRequest = {\n params: {\n invoice?: string;\n sendPaymentParams: Record<string, unknown>;\n };\n options?: {\n idempotencyKey?: string;\n maxRetries?: number;\n };\n};\n\nexport type RuntimeChannelJobRequest = {\n params: {\n action: 'open' | 'shutdown' | 'accept' | 'abandon' | 'update';\n openChannelParams?: Record<string, unknown>;\n shutdownChannelParams?: Record<string, unknown>;\n acceptChannelParams?: Record<string, unknown>;\n abandonChannelParams?: Record<string, unknown>;\n updateChannelParams?: Record<string, unknown>;\n peerId?: string;\n channelId?: string;\n waitForReady?: boolean;\n waitForClosed?: boolean;\n pollIntervalMs?: number;\n };\n options?: {\n idempotencyKey?: string;\n maxRetries?: number;\n reuseTerminal?: boolean;\n };\n};\n\nexport type RuntimeInvoiceJobRequest = {\n params: {\n action: 'create' | 'watch' | 'cancel' | 'settle';\n newInvoiceParams?: Record<string, unknown>;\n getInvoicePaymentHash?: string;\n cancelInvoiceParams?: Record<string, unknown>;\n settleInvoiceParams?: Record<string, unknown>;\n waitForTerminal?: boolean;\n pollIntervalMs?: number;\n };\n options?: {\n idempotencyKey?: string;\n maxRetries?: number;\n };\n};\n\nexport async function tryCreateRuntimePaymentJob(\n runtimeUrl: string,\n body: RuntimePaymentJobRequest,\n): Promise<RuntimeJobRecord | null> {\n try {\n const response = await fetch(`${runtimeUrl}/jobs/payment`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(body),\n });\n if (!response.ok) return null;\n return (await response.json()) as RuntimeJobRecord;\n } catch {\n return null;\n }\n}\n\nexport async function tryCreateRuntimeChannelJob(\n runtimeUrl: string,\n body: RuntimeChannelJobRequest,\n): Promise<RuntimeJobRecord | null> {\n try {\n const response = await fetch(`${runtimeUrl}/jobs/channel`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(body),\n });\n if (!response.ok) return null;\n return (await response.json()) as RuntimeJobRecord;\n } catch {\n return null;\n }\n}\n\nexport async function tryCreateRuntimeInvoiceJob(\n runtimeUrl: string,\n body: RuntimeInvoiceJobRequest,\n): Promise<RuntimeJobRecord | null> {\n try {\n const response = await fetch(`${runtimeUrl}/jobs/invoice`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(body),\n });\n if (!response.ok) return null;\n return (await response.json()) as RuntimeJobRecord;\n } catch {\n return null;\n }\n}\n\nexport async function waitForRuntimeJobTerminal(\n runtimeUrl: string,\n jobId: string,\n timeoutSeconds: number,\n): Promise<RuntimeJobRecord> {\n const startedAt = Date.now();\n while (Date.now() - startedAt < timeoutSeconds * 1000) {\n const response = await fetch(`${runtimeUrl}/jobs/${jobId}`);\n if (!response.ok) {\n throw new Error(`Failed to fetch runtime job ${jobId}: ${response.status}`);\n }\n const job = (await response.json()) as RuntimeJobRecord;\n if (job.state === 'succeeded' || job.state === 'failed' || job.state === 'cancelled') {\n return job;\n }\n await sleep(500);\n }\n throw new Error(`Timed out waiting for runtime job ${jobId}`);\n}\n","import { ckbToShannons, type HexString, shannonsToCkb } from '@fiber-pay/sdk';\nimport type { Command } from 'commander';\nimport type { CliConfig } from '../lib/config.js';\nimport { printJsonError, printJsonSuccess } from '../lib/format.js';\nimport { createReadyRpcClient } from '../lib/rpc.js';\n\ninterface RebalanceExecutionParams {\n amountInput: string;\n maxFeeInput?: string;\n hops?: string[];\n dryRun: boolean;\n json: boolean;\n errorCode: 'PAYMENT_REBALANCE_INPUT_INVALID' | 'CHANNEL_REBALANCE_INPUT_INVALID';\n}\n\nasync function executeRebalance(\n config: CliConfig,\n params: RebalanceExecutionParams,\n): Promise<void> {\n const rpc = await createReadyRpcClient(config);\n const amountCkb = parseFloat(params.amountInput);\n const maxFeeCkb = params.maxFeeInput !== undefined ? parseFloat(params.maxFeeInput) : undefined;\n const manualHops = params.hops ?? [];\n\n if (!Number.isFinite(amountCkb) || amountCkb <= 0) {\n const message = 'Invalid --amount value. Expected a positive CKB amount.';\n if (params.json) {\n printJsonError({\n code: params.errorCode,\n message,\n recoverable: true,\n suggestion: 'Provide a positive number, e.g. `--amount 10`.',\n details: { amount: params.amountInput },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n\n if (\n maxFeeCkb !== undefined &&\n (!Number.isFinite(maxFeeCkb) || maxFeeCkb < 0 || manualHops.length > 0)\n ) {\n const message =\n manualHops.length > 0\n ? '--max-fee is only supported in auto rebalance mode (without manual hops).'\n : 'Invalid --max-fee value. Expected a non-negative CKB amount.';\n if (params.json) {\n printJsonError({\n code: params.errorCode,\n message,\n recoverable: true,\n suggestion:\n manualHops.length > 0\n ? 'Remove `--max-fee` or run auto mode without manual hops.'\n : 'Provide a non-negative number, e.g. `--max-fee 0.01`.',\n details: { maxFee: params.maxFeeInput, hasManualHops: manualHops.length > 0 },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n\n const selfPubkey = (await rpc.nodeInfo()).node_id as HexString;\n const amount = ckbToShannons(amountCkb);\n const isManual = manualHops.length > 0;\n let routeHopCount: number | undefined;\n\n const result = isManual\n ? await (async () => {\n const hopsInfo = [\n ...manualHops.map((pubkey: string) => ({ pubkey: pubkey as HexString })),\n ...(manualHops[manualHops.length - 1] === selfPubkey\n ? []\n : [{ pubkey: selfPubkey as HexString }]),\n ];\n\n const route = await rpc.buildRouter({\n amount,\n hops_info: hopsInfo,\n });\n routeHopCount = route.router_hops.length;\n\n return rpc.sendPaymentWithRouter({\n router: route.router_hops,\n keysend: true,\n allow_self_payment: true,\n dry_run: params.dryRun ? true : undefined,\n });\n })()\n : await rpc.sendPayment({\n target_pubkey: selfPubkey,\n amount,\n keysend: true,\n allow_self_payment: true,\n max_fee_amount: maxFeeCkb !== undefined ? ckbToShannons(maxFeeCkb) : undefined,\n dry_run: params.dryRun ? true : undefined,\n });\n\n const payload = {\n mode: isManual ? 'manual' : 'auto',\n selfPubkey,\n amountCkb,\n maxFeeCkb: isManual ? undefined : maxFeeCkb,\n routeHopCount,\n paymentHash: result.payment_hash,\n status:\n result.status === 'Success' ? 'success' : result.status === 'Failed' ? 'failed' : 'pending',\n feeCkb: shannonsToCkb(result.fee),\n failureReason: result.failed_error,\n dryRun: params.dryRun,\n };\n\n if (params.json) {\n printJsonSuccess(payload);\n } else {\n console.log(\n payload.dryRun\n ? `Rebalance dry-run complete (${payload.mode} route)`\n : `Rebalance sent (${payload.mode} route)`,\n );\n console.log(` Self: ${payload.selfPubkey}`);\n console.log(` Amount: ${payload.amountCkb} CKB`);\n if (payload.mode === 'manual' && payload.routeHopCount !== undefined) {\n console.log(` Hops: ${payload.routeHopCount}`);\n }\n console.log(` Hash: ${payload.paymentHash}`);\n console.log(` Status: ${payload.status}`);\n console.log(` Fee: ${payload.feeCkb} CKB`);\n if (payload.mode === 'auto' && payload.maxFeeCkb !== undefined) {\n console.log(` MaxFee: ${payload.maxFeeCkb} CKB`);\n }\n if (payload.failureReason) {\n console.log(` Error: ${payload.failureReason}`);\n }\n }\n}\n\nexport function registerPaymentRebalanceCommand(parent: Command, config: CliConfig): void {\n parent\n .command('rebalance')\n .description('Technical rebalance command mapped to payment-layer circular self-payment')\n .requiredOption('--amount <ckb>', 'Amount in CKB to rebalance')\n .option('--max-fee <ckb>', 'Maximum fee in CKB (auto mode only)')\n .option(\n '--hops <pubkeys>',\n 'Comma-separated peer pubkeys for manual route mode (self pubkey appended automatically)',\n )\n .option('--dry-run', 'Simulate route/payment and return estimated result')\n .option('--json')\n .action(async (options) => {\n const hasHopsOption = typeof options.hops === 'string';\n const manualHops = hasHopsOption\n ? options.hops\n .split(',')\n .map((item: string) => item.trim())\n .filter(Boolean)\n : [];\n\n if (hasHopsOption && manualHops.length === 0) {\n const message =\n 'Invalid --hops value. Expected a non-empty comma-separated list of pubkeys.';\n if (options.json) {\n printJsonError({\n code: 'PAYMENT_REBALANCE_INPUT_INVALID',\n message,\n recoverable: true,\n suggestion: 'Provide pubkeys like `--hops 0xabc...,0xdef...`.',\n details: { hops: options.hops },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n\n await executeRebalance(config, {\n amountInput: options.amount,\n maxFeeInput: options.maxFee,\n hops: manualHops,\n dryRun: Boolean(options.dryRun),\n json: Boolean(options.json),\n errorCode: 'PAYMENT_REBALANCE_INPUT_INVALID',\n });\n });\n}\n\nexport function registerChannelRebalanceCommand(parent: Command, config: CliConfig): void {\n parent\n .command('rebalance')\n .description('High-level channel rebalance wrapper using payment-layer orchestration')\n .requiredOption('--amount <ckb>', 'Amount in CKB to rebalance')\n .option('--from-channel <channelId>', 'Source-biased channel id (optional)')\n .option('--to-channel <channelId>', 'Destination-biased channel id (optional)')\n .option('--max-fee <ckb>', 'Maximum fee in CKB (auto mode only)')\n .option('--dry-run', 'Simulate route/payment and return estimated result')\n .option('--json')\n .action(async (options) => {\n const json = Boolean(options.json);\n const fromChannelId = options.fromChannel as string | undefined;\n const toChannelId = options.toChannel as string | undefined;\n\n if ((fromChannelId && !toChannelId) || (!fromChannelId && toChannelId)) {\n const message =\n 'Both --from-channel and --to-channel must be provided together for guided channel rebalance.';\n if (json) {\n printJsonError({\n code: 'CHANNEL_REBALANCE_INPUT_INVALID',\n message,\n recoverable: true,\n suggestion: 'Provide both channel ids, or provide neither to run auto mode.',\n details: { fromChannel: fromChannelId, toChannel: toChannelId },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n\n let guidedHops: string[] | undefined;\n if (fromChannelId && toChannelId) {\n const rpc = await createReadyRpcClient(config);\n const channels = (await rpc.listChannels({ include_closed: true })).channels;\n const fromChannel = channels.find((item) => item.channel_id === fromChannelId);\n const toChannel = channels.find((item) => item.channel_id === toChannelId);\n\n if (!fromChannel || !toChannel) {\n const message = 'Invalid channel selection: source/target channel id not found.';\n if (json) {\n printJsonError({\n code: 'CHANNEL_REBALANCE_INPUT_INVALID',\n message,\n recoverable: true,\n suggestion: 'Run `channel list --json` and retry with valid channel ids.',\n details: { fromChannel: fromChannelId, toChannel: toChannelId },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n\n if (fromChannel.peer_id === toChannel.peer_id) {\n const message =\n 'Source and target channels point to the same peer; choose two different channel peers.';\n if (json) {\n printJsonError({\n code: 'CHANNEL_REBALANCE_INPUT_INVALID',\n message,\n recoverable: true,\n suggestion: 'Select channels with different peer ids for guided rebalance.',\n details: {\n fromChannel: fromChannelId,\n toChannel: toChannelId,\n peerId: fromChannel.peer_id,\n },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n\n const peers = (await rpc.listPeers()).peers;\n const pubkeyByPeerId = new Map(peers.map((peer) => [peer.peer_id, peer.pubkey]));\n const fromPubkey = pubkeyByPeerId.get(fromChannel.peer_id);\n const toPubkey = pubkeyByPeerId.get(toChannel.peer_id);\n\n if (!fromPubkey || !toPubkey) {\n const message =\n 'Unable to resolve selected channel peer_id to pubkey for guided rebalance route.';\n if (json) {\n printJsonError({\n code: 'CHANNEL_REBALANCE_INPUT_INVALID',\n message,\n recoverable: true,\n suggestion:\n 'Ensure both peers are connected (`peer list --json`) and retry guided mode, or use `payment rebalance --hops`.',\n details: {\n fromChannel: fromChannelId,\n toChannel: toChannelId,\n fromPeerId: fromChannel.peer_id,\n toPeerId: toChannel.peer_id,\n resolvedPeers: peers.length,\n },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n\n guidedHops = [fromPubkey, toPubkey];\n }\n\n await executeRebalance(config, {\n amountInput: options.amount,\n maxFeeInput: options.maxFee,\n hops: guidedHops,\n dryRun: Boolean(options.dryRun),\n json,\n errorCode: 'CHANNEL_REBALANCE_INPUT_INVALID',\n });\n });\n}\n","import { existsSync, readFileSync, writeFileSync } from 'node:fs';\nimport { Command } from 'commander';\nimport { parseDocument, stringify as yamlStringify } from 'yaml';\nimport {\n type CliConfig,\n getEffectiveConfig,\n loadProfileConfig,\n type ProfileConfig,\n parseNetworkFromConfig,\n saveProfileConfig,\n writeNetworkConfigFile,\n} from '../lib/config.js';\nimport type { FiberNetwork } from '../lib/config-templates.js';\nimport { printJsonError, printJsonSuccess } from '../lib/format.js';\n\nfunction parseNetworkInput(input: string | undefined): FiberNetwork {\n if (!input) return 'testnet';\n if (input === 'testnet' || input === 'mainnet') return input;\n throw new Error(`Invalid network: ${input}. Expected one of: testnet, mainnet`);\n}\n\nfunction parsePortInput(\n input: string | undefined,\n label: 'rpc-port' | 'p2p-port' | 'proxy-port',\n): number | undefined {\n if (input === undefined) return undefined;\n const parsed = Number.parseInt(input, 10);\n if (!Number.isInteger(parsed) || parsed < 1 || parsed > 65535) {\n throw new Error(`Invalid ${label}: ${input}. Expected integer in range 1-65535.`);\n }\n return parsed;\n}\n\nfunction resolvePort(\n optionValue: string | undefined,\n envValue: string | undefined,\n label: 'rpc-port' | 'p2p-port',\n): { value: number | undefined; source: 'option' | 'env' | 'unset' } {\n if (optionValue !== undefined) {\n return { value: parsePortInput(optionValue, label), source: 'option' };\n }\n if (envValue !== undefined) {\n return { value: parsePortInput(envValue, label), source: 'env' };\n }\n return { value: undefined, source: 'unset' };\n}\n\ntype ConfigValueType = 'auto' | 'string' | 'number' | 'boolean' | 'null' | 'json';\ntype ConfigPathSegment = string | number;\n\nconst LEGACY_PATH_ALIASES: Record<string, string> = {\n chain: 'fiber.chain',\n};\n\nfunction resolveConfigPathAlias(path: string): string {\n return LEGACY_PATH_ALIASES[path] ?? path;\n}\n\nfunction parseConfigPath(path: string): ConfigPathSegment[] {\n const normalized = resolveConfigPathAlias(path).trim();\n if (!normalized) {\n throw new Error('Config path cannot be empty.');\n }\n\n const segments: ConfigPathSegment[] = [];\n const re = /([^.[\\]]+)|\\[(\\d+)\\]/g;\n for (const match of normalized.matchAll(re)) {\n if (match[1]) {\n segments.push(match[1]);\n } else if (match[2]) {\n segments.push(Number.parseInt(match[2], 10));\n }\n }\n\n if (segments.length === 0) {\n throw new Error(`Invalid config path: ${path}`);\n }\n\n return segments;\n}\n\nfunction parseTypedValue(raw: string, valueType: ConfigValueType): unknown {\n if (valueType === 'string') return raw;\n if (valueType === 'null') return null;\n\n if (valueType === 'number') {\n const parsed = Number(raw);\n if (!Number.isFinite(parsed)) {\n throw new Error(`Invalid number value: ${raw}`);\n }\n return parsed;\n }\n\n if (valueType === 'boolean') {\n const lowered = raw.toLowerCase();\n if (lowered === 'true') return true;\n if (lowered === 'false') return false;\n throw new Error(`Invalid boolean value: ${raw}. Expected true or false.`);\n }\n\n if (valueType === 'json') {\n try {\n return JSON.parse(raw);\n } catch {\n throw new Error(`Invalid JSON value: ${raw}`);\n }\n }\n\n const lowered = raw.toLowerCase();\n if (lowered === 'true') return true;\n if (lowered === 'false') return false;\n if (lowered === 'null') return null;\n\n if (/^-?\\d+(\\.\\d+)?$/.test(raw)) {\n return Number(raw);\n }\n\n if ((raw.startsWith('{') && raw.endsWith('}')) || (raw.startsWith('[') && raw.endsWith(']'))) {\n try {\n return JSON.parse(raw);\n } catch {\n return raw;\n }\n }\n\n return raw;\n}\n\nfunction ensureConfigFileOrExit(configPath: string, json: boolean): void {\n if (!existsSync(configPath)) {\n const msg = `Config file not found: ${configPath}. Run \\`fiber-pay config init\\` first.`;\n if (json) {\n printJsonError({\n code: 'CONFIG_NOT_FOUND',\n message: msg,\n recoverable: true,\n suggestion: 'Run `fiber-pay config init --network testnet` and retry.',\n });\n } else {\n console.error(`Error: ${msg}`);\n }\n process.exit(1);\n }\n}\n\nfunction normalizeHexScalarsForMutation(content: string): string {\n return content.replace(\n /^(\\s*)(code_hash|tx_hash|args):\\s*(0x[0-9a-fA-F]+)(\\s*(#.*))?$/gm,\n (_match, indent: string, key: string, value: string, tail = '') =>\n `${indent}${key}: \"${value}\"${tail}`,\n );\n}\n\nfunction parseConfigDocumentForMutation(configPath: string) {\n const raw = readFileSync(configPath, 'utf-8');\n const normalized = normalizeHexScalarsForMutation(raw);\n return parseDocument(normalized, {\n keepSourceTokens: true,\n });\n}\n\nfunction collectConfigPaths(value: unknown, prefix = ''): string[] {\n if (value === null || value === undefined) {\n return prefix ? [prefix] : [];\n }\n\n if (Array.isArray(value)) {\n if (value.length === 0) {\n return prefix ? [prefix] : [];\n }\n const result: string[] = [];\n for (let index = 0; index < value.length; index++) {\n const childPrefix = `${prefix}[${index}]`;\n result.push(...collectConfigPaths(value[index], childPrefix));\n }\n return result;\n }\n\n if (typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>);\n if (entries.length === 0) {\n return prefix ? [prefix] : [];\n }\n const result: string[] = [];\n for (const [key, child] of entries) {\n const childPrefix = prefix ? `${prefix}.${key}` : key;\n result.push(...collectConfigPaths(child, childPrefix));\n }\n return result;\n }\n\n return prefix ? [prefix] : [];\n}\n\nexport function createConfigCommand(_config: CliConfig): Command {\n const config = new Command('config').description('Single source configuration management');\n\n config\n .command('init')\n .option(\n '--data-dir <path>',\n 'Target data directory (overrides FIBER_DATA_DIR for this command)',\n )\n .option('--network <network>', 'testnet | mainnet')\n .option('--rpc-port <port>', 'Override rpc.listening_addr port in generated config')\n .option('--p2p-port <port>', 'Override fiber.listening_addr port in generated config')\n .option('--proxy-port <port>', 'Set runtime proxy port and persist in profile.json')\n .option('--force', 'Overwrite existing config file')\n .option('--json')\n .action(async (options) => {\n const effective = getEffectiveConfig();\n const dataDir = options.dataDir ?? effective.config.dataDir;\n const selectedNetwork = options.network\n ? parseNetworkInput(options.network)\n : effective.config.network;\n const rpcPort = resolvePort(options.rpcPort, process.env.FIBER_RPC_PORT, 'rpc-port');\n const p2pPort = resolvePort(options.p2pPort, process.env.FIBER_P2P_PORT, 'p2p-port');\n const result = writeNetworkConfigFile(dataDir, selectedNetwork, {\n force: Boolean(options.force),\n rpcPort: rpcPort.value,\n p2pPort: p2pPort.value,\n });\n\n // Persist proxy port into profile.json if specified\n let proxyPort: number | undefined;\n if (options.proxyPort !== undefined) {\n proxyPort = parsePortInput(options.proxyPort, 'proxy-port');\n const existing = loadProfileConfig(dataDir) ?? {};\n existing.runtimeProxyListen = `127.0.0.1:${proxyPort}`;\n saveProfileConfig(dataDir, existing);\n }\n\n const payload = {\n configPath: result.path,\n dataDir,\n network: selectedNetwork,\n rpcPort: rpcPort.value,\n rpcPortSource: rpcPort.source,\n p2pPort: p2pPort.value,\n p2pPortSource: p2pPort.source,\n proxyPort: proxyPort ?? null,\n created: result.created,\n overwritten: result.overwritten,\n skipped: !result.created && !result.overwritten,\n };\n\n if (options.json) {\n printJsonSuccess(payload);\n } else {\n if (result.created) {\n console.log(`✅ Config initialized: ${result.path}`);\n } else if (result.overwritten) {\n console.log(`✅ Config overwritten: ${result.path}`);\n } else {\n console.log(`ℹ️ Config already exists: ${result.path}`);\n console.log(' Use --force to overwrite.');\n }\n if (options.dataDir !== undefined) {\n console.log(` Data Dir: ${dataDir} (option)`);\n } else {\n console.log(` Data Dir: ${dataDir} (${effective.sources.dataDir})`);\n }\n console.log(` Network: ${selectedNetwork}`);\n if (rpcPort.value !== undefined)\n console.log(` RPC Port: ${rpcPort.value} (${rpcPort.source})`);\n if (p2pPort.value !== undefined)\n console.log(` P2P Port: ${p2pPort.value} (${p2pPort.source})`);\n if (proxyPort !== undefined) console.log(` Proxy Port: ${proxyPort} (profile.json)`);\n }\n });\n\n config\n .command('show')\n .option('--effective', 'Debug resolved values and value source')\n .option('--json')\n .action(async (options) => {\n const effective = getEffectiveConfig();\n\n if (options.effective) {\n const payload = {\n config: effective.config,\n sources: effective.sources,\n configExists: effective.configExists,\n };\n\n if (options.json) {\n printJsonSuccess(payload);\n } else {\n console.log('Effective Config');\n console.log(` Data Dir: ${effective.config.dataDir} (${effective.sources.dataDir})`);\n console.log(` Config Path: ${effective.config.configPath}`);\n console.log(` Network: ${effective.config.network} (${effective.sources.network})`);\n console.log(` RPC URL: ${effective.config.rpcUrl} (${effective.sources.rpcUrl})`);\n console.log(` Exists: ${effective.configExists ? 'yes' : 'no'}`);\n }\n return;\n }\n\n if (!effective.configExists) {\n if (options.json) {\n printJsonError({\n code: 'CONFIG_NOT_FOUND',\n message: `Config file not found: ${effective.config.configPath}`,\n recoverable: true,\n suggestion: 'Run `fiber-pay config init --network testnet` and retry.',\n details: { configPath: effective.config.configPath },\n });\n } else {\n console.error(`Error: Config file not found: ${effective.config.configPath}`);\n console.error('Run: fiber-pay config init --network testnet');\n }\n process.exit(1);\n }\n\n const content = readFileSync(effective.config.configPath, 'utf-8');\n const fileNetwork = parseNetworkFromConfig(content) || 'unknown';\n\n if (options.json) {\n printJsonSuccess({\n path: effective.config.configPath,\n network: fileNetwork,\n content,\n });\n } else {\n console.log(`# ${effective.config.configPath} (${fileNetwork})`);\n console.log(content);\n }\n });\n\n config\n .command('get')\n .description('Get config value by path (e.g. fiber.chain, ckb.udt_whitelist[0].name)')\n .argument('<path>', 'Config path')\n .option('--json')\n .action(async (path, options) => {\n const effective = getEffectiveConfig();\n const json = Boolean(options.json);\n const configPath = effective.config.configPath;\n ensureConfigFileOrExit(configPath, json);\n\n const doc = parseConfigDocumentForMutation(configPath);\n const segments = parseConfigPath(path);\n const value = doc.getIn(segments as (string | number)[]);\n\n if (value === undefined) {\n const msg = `Config path not found: ${resolveConfigPathAlias(path)}`;\n if (json) {\n printJsonError({\n code: 'CONFIG_PATH_NOT_FOUND',\n message: msg,\n recoverable: true,\n suggestion: 'Use `fiber-pay config list` to inspect available paths.',\n });\n } else {\n console.error(`Error: ${msg}`);\n }\n process.exit(1);\n }\n\n if (json) {\n printJsonSuccess({ path: resolveConfigPathAlias(path), value });\n } else if (typeof value === 'object') {\n console.log(yamlStringify(value).trimEnd());\n } else {\n console.log(String(value));\n }\n });\n\n config\n .command('set')\n .description('Set config value by path (supports nested keys and array indexes)')\n .argument('<path>', 'Config path')\n .argument('<value>', 'New value')\n .option('--type <type>', 'auto|string|number|boolean|null|json', 'auto')\n .option('--json')\n .action(async (path, value, options) => {\n const effective = getEffectiveConfig();\n const json = Boolean(options.json);\n const configPath = effective.config.configPath;\n ensureConfigFileOrExit(configPath, json);\n\n const valueType = String(options.type ?? 'auto') as ConfigValueType;\n if (!['auto', 'string', 'number', 'boolean', 'null', 'json'].includes(valueType)) {\n const msg = `Invalid --type: ${options.type}. Expected auto|string|number|boolean|null|json`;\n if (json) {\n printJsonError({\n code: 'CONFIG_VALUE_TYPE_INVALID',\n message: msg,\n recoverable: true,\n });\n } else {\n console.error(`Error: ${msg}`);\n }\n process.exit(1);\n }\n\n const doc = parseConfigDocumentForMutation(configPath);\n const resolvedPath = resolveConfigPathAlias(path);\n const segments = parseConfigPath(path);\n const parsedValue = parseTypedValue(value, valueType);\n\n doc.setIn(segments as (string | number)[], parsedValue);\n writeFileSync(configPath, doc.toString({ lineWidth: 0 }), 'utf-8');\n\n if (json) {\n printJsonSuccess({ path: resolvedPath, value: parsedValue, configPath });\n } else {\n console.log(`✅ Set ${resolvedPath} = ${value} in ${configPath}`);\n }\n });\n\n config\n .command('unset')\n .description('Remove config value by path')\n .argument('<path>', 'Config path')\n .option('--json')\n .action(async (path, options) => {\n const effective = getEffectiveConfig();\n const json = Boolean(options.json);\n const configPath = effective.config.configPath;\n ensureConfigFileOrExit(configPath, json);\n\n const doc = parseConfigDocumentForMutation(configPath);\n const resolvedPath = resolveConfigPathAlias(path);\n const segments = parseConfigPath(path);\n const removed = doc.deleteIn(segments as (string | number)[]);\n\n if (!removed) {\n const msg = `Config path not found: ${resolvedPath}`;\n if (json) {\n printJsonError({\n code: 'CONFIG_PATH_NOT_FOUND',\n message: msg,\n recoverable: true,\n suggestion: 'Use `fiber-pay config list` to inspect available paths.',\n });\n } else {\n console.error(`Error: ${msg}`);\n }\n process.exit(1);\n }\n\n writeFileSync(configPath, doc.toString({ lineWidth: 0 }), 'utf-8');\n\n if (json) {\n printJsonSuccess({ path: resolvedPath, removed: true, configPath });\n } else {\n console.log(`✅ Removed ${resolvedPath} from ${configPath}`);\n }\n });\n\n config\n .command('list')\n .description('List config key paths (optionally under a prefix)')\n .option('--prefix <path>', 'List only under this path')\n .option('--json')\n .action(async (options) => {\n const effective = getEffectiveConfig();\n const json = Boolean(options.json);\n const configPath = effective.config.configPath;\n ensureConfigFileOrExit(configPath, json);\n\n const doc = parseConfigDocumentForMutation(configPath);\n const prefix = options.prefix ? resolveConfigPathAlias(String(options.prefix)) : undefined;\n\n let rootValue: unknown = doc.toJSON();\n let basePrefix = '';\n\n if (prefix) {\n const segments = parseConfigPath(prefix);\n rootValue = doc.getIn(segments as (string | number)[]);\n if (rootValue === undefined) {\n const msg = `Config path not found: ${prefix}`;\n if (json) {\n printJsonError({\n code: 'CONFIG_PATH_NOT_FOUND',\n message: msg,\n recoverable: true,\n suggestion: 'Use `fiber-pay config list` without prefix first.',\n });\n } else {\n console.error(`Error: ${msg}`);\n }\n process.exit(1);\n }\n basePrefix = prefix;\n }\n\n const paths = collectConfigPaths(rootValue, basePrefix).sort((a, b) => a.localeCompare(b));\n\n if (json) {\n printJsonSuccess({ prefix: prefix ?? null, paths, count: paths.length });\n } else {\n for (const path of paths) {\n console.log(path);\n }\n }\n });\n\n // ---------------------------------------------------------------------------\n // config profile — manage profile.json key-value settings\n // ---------------------------------------------------------------------------\n const profile = new Command('profile').description(\n 'Manage profile.json settings (CLI-only overrides)',\n );\n\n const PROFILE_KEYS: (keyof ProfileConfig)[] = ['binaryPath', 'keyPassword', 'runtimeProxyListen'];\n\n profile\n .command('show')\n .description('Show current profile.json values')\n .option('--json')\n .action(async (options) => {\n const effective = getEffectiveConfig();\n const profileData = loadProfileConfig(effective.config.dataDir);\n\n if (options.json) {\n printJsonSuccess({ dataDir: effective.config.dataDir, profile: profileData ?? {} });\n } else {\n if (!profileData || Object.keys(profileData).length === 0) {\n console.log('No profile settings found.');\n console.log(` Location: ${effective.config.dataDir}/profile.json`);\n return;\n }\n console.log('Profile Settings');\n console.log(` Location: ${effective.config.dataDir}/profile.json`);\n for (const key of PROFILE_KEYS) {\n if (profileData[key] !== undefined) {\n console.log(` ${key}: ${profileData[key]}`);\n }\n }\n }\n });\n\n profile\n .command('set')\n .description('Set a profile key')\n .argument('<key>', `One of: ${PROFILE_KEYS.join(', ')}`)\n .argument('<value>')\n .option('--json')\n .action(async (key, value, options) => {\n if (!PROFILE_KEYS.includes(key as keyof ProfileConfig)) {\n const msg = `Unknown profile key: ${key}. Valid keys: ${PROFILE_KEYS.join(', ')}`;\n if (options.json) {\n printJsonError({\n code: 'PROFILE_INVALID_KEY',\n message: msg,\n recoverable: true,\n suggestion: `Use one of: ${PROFILE_KEYS.join(', ')}`,\n });\n } else {\n console.error(`Error: ${msg}`);\n }\n process.exit(1);\n }\n\n const effective = getEffectiveConfig();\n const existing = loadProfileConfig(effective.config.dataDir) ?? {};\n\n (existing as Record<string, unknown>)[key] = value;\n saveProfileConfig(effective.config.dataDir, existing);\n\n if (options.json) {\n printJsonSuccess({ key, value, dataDir: effective.config.dataDir });\n } else {\n console.log(`✅ Profile key \"${key}\" set to \"${value}\"`);\n }\n });\n\n profile\n .command('unset')\n .description('Remove a profile key')\n .argument('<key>', `One of: ${PROFILE_KEYS.join(', ')}`)\n .option('--json')\n .action(async (key, options) => {\n if (!PROFILE_KEYS.includes(key as keyof ProfileConfig)) {\n const msg = `Unknown profile key: ${key}. Valid keys: ${PROFILE_KEYS.join(', ')}`;\n if (options.json) {\n printJsonError({\n code: 'PROFILE_INVALID_KEY',\n message: msg,\n recoverable: true,\n suggestion: `Use one of: ${PROFILE_KEYS.join(', ')}`,\n });\n } else {\n console.error(`Error: ${msg}`);\n }\n process.exit(1);\n }\n\n const effective = getEffectiveConfig();\n const existing = loadProfileConfig(effective.config.dataDir) ?? {};\n delete (existing as Record<string, unknown>)[key];\n saveProfileConfig(effective.config.dataDir, existing);\n\n if (options.json) {\n printJsonSuccess({ key, removed: true, dataDir: effective.config.dataDir });\n } else {\n console.log(`✅ Profile key \"${key}\" removed`);\n }\n });\n\n config.addCommand(profile);\n\n return config;\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { type FiberNetwork, getConfigTemplate } from './config-templates.js';\n\nexport interface CliConfig {\n binaryPath?: string;\n dataDir: string;\n configPath: string;\n network: FiberNetwork;\n rpcUrl: string;\n rpcBiscuitToken?: string;\n keyPassword?: string;\n ckbRpcUrl?: string;\n runtimeProxyListen?: string;\n}\n\n/** Keys that can be stored in a profile.json file. */\nexport interface ProfileConfig {\n binaryPath?: string;\n keyPassword?: string;\n runtimeProxyListen?: string;\n}\n\nexport interface EffectiveConfigSources {\n dataDir: 'cli' | 'env' | 'default';\n configPath: 'derived';\n network: 'cli' | 'env' | 'config' | 'default';\n rpcUrl: 'cli' | 'env' | 'config' | 'default';\n rpcBiscuitToken?: 'cli' | 'env' | 'unset';\n ckbRpcUrl?: 'env' | 'config' | 'unset';\n runtimeProxyListen?: 'cli' | 'env' | 'profile' | 'default';\n}\n\nexport interface EffectiveConfig {\n config: CliConfig;\n sources: EffectiveConfigSources;\n configExists: boolean;\n}\n\nconst DEFAULT_DATA_DIR = `${process.env.HOME}/.fiber-pay`;\nconst DEFAULT_RPC_URL = 'http://127.0.0.1:8227';\nconst DEFAULT_NETWORK: FiberNetwork = 'testnet';\n\nexport function getConfigPath(dataDir: string): string {\n return join(dataDir, 'config.yml');\n}\n\nexport function parseNetworkFromConfig(configContent: string): FiberNetwork | undefined {\n const match = configContent.match(/^\\s*chain:\\s*(testnet|mainnet)\\s*$/m);\n if (!match) return undefined;\n return match[1] as FiberNetwork;\n}\n\nexport function parseRpcUrlFromConfig(configContent: string): string | undefined {\n const rpcSectionMatch = configContent.match(\n /(^|\\n)rpc:\\n([\\s\\S]*?)(\\n[a-zA-Z_]+:|\\nservices:|$)/,\n );\n const rpcSection = rpcSectionMatch?.[2];\n if (!rpcSection) return undefined;\n\n const match = rpcSection.match(/^\\s*listening_addr:\\s*\"?([^\"\\n]+)\"?\\s*$/m);\n if (!match) return undefined;\n const listeningAddr = match[1].trim();\n if (!listeningAddr) return undefined;\n if (listeningAddr.startsWith('http://') || listeningAddr.startsWith('https://')) {\n return listeningAddr;\n }\n return `http://${listeningAddr}`;\n}\n\nexport function parseCkbRpcUrlFromConfig(configContent: string): string | undefined {\n const ckbSectionMatch = configContent.match(\n /(^|\\n)ckb:\\n([\\s\\S]*?)(\\n[a-zA-Z_]+:|\\nservices:|$)/,\n );\n const ckbSection = ckbSectionMatch?.[2];\n if (!ckbSection) return undefined;\n\n const match = ckbSection.match(/^\\s*rpc_url:\\s*\"?([^\"\\n]+)\"?\\s*$/m);\n return match?.[1]?.trim() || undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Profile helpers\n// ---------------------------------------------------------------------------\n\nfunction getProfilePath(dataDir: string): string {\n return join(dataDir, 'profile.json');\n}\n\nexport function loadProfileConfig(dataDir: string): ProfileConfig | undefined {\n const profilePath = getProfilePath(dataDir);\n if (!existsSync(profilePath)) return undefined;\n try {\n const raw = readFileSync(profilePath, 'utf-8');\n return JSON.parse(raw) as ProfileConfig;\n } catch {\n return undefined;\n }\n}\n\nexport function saveProfileConfig(dataDir: string, profile: ProfileConfig): void {\n if (!existsSync(dataDir)) {\n mkdirSync(dataDir, { recursive: true });\n }\n const profilePath = getProfilePath(dataDir);\n writeFileSync(profilePath, `${JSON.stringify(profile, null, 2)}\\n`, 'utf-8');\n}\n\nexport function writeNetworkConfigFile(\n dataDir: string,\n network: FiberNetwork,\n options: { force?: boolean; rpcPort?: number; p2pPort?: number } = {},\n): { path: string; created: boolean; overwritten: boolean } {\n const configPath = getConfigPath(dataDir);\n const alreadyExists = existsSync(configPath);\n\n if (alreadyExists && !options.force) {\n return { path: configPath, created: false, overwritten: false };\n }\n\n if (!existsSync(dataDir)) {\n mkdirSync(dataDir, { recursive: true });\n }\n\n let content = getConfigTemplate(network);\n\n if (options.rpcPort !== undefined || options.p2pPort !== undefined) {\n const lines = content.split('\\n');\n let section: string | null = null;\n\n for (let i = 0; i < lines.length; i++) {\n const sectionMatch = lines[i].match(/^([a-zA-Z_]+):\\s*$/);\n if (sectionMatch) {\n section = sectionMatch[1];\n continue;\n }\n\n if (\n section === 'fiber' &&\n options.p2pPort !== undefined &&\n /^\\s*listening_addr:\\s*/.test(lines[i])\n ) {\n lines[i] = ` listening_addr: \"/ip4/127.0.0.1/tcp/${options.p2pPort}\"`;\n } else if (\n section === 'rpc' &&\n options.rpcPort !== undefined &&\n /^\\s*listening_addr:\\s*/.test(lines[i])\n ) {\n lines[i] = ` listening_addr: \"127.0.0.1:${options.rpcPort}\"`;\n }\n }\n\n content = lines.join('\\n');\n }\n\n writeFileSync(configPath, content, 'utf-8');\n return { path: configPath, created: !alreadyExists, overwritten: alreadyExists };\n}\n\nexport function ensureNodeConfigFile(dataDir: string, network: FiberNetwork): string {\n const configPath = getConfigPath(dataDir);\n if (!existsSync(configPath)) {\n writeNetworkConfigFile(dataDir, network);\n }\n return configPath;\n}\n\nexport function getEffectiveConfig(explicitFlags?: Set<string>): EffectiveConfig {\n const dataDir = process.env.FIBER_DATA_DIR || DEFAULT_DATA_DIR;\n const dataDirSource: EffectiveConfigSources['dataDir'] = explicitFlags?.has('dataDir')\n ? 'cli'\n : process.env.FIBER_DATA_DIR\n ? 'env'\n : 'default';\n\n const configPath = getConfigPath(dataDir);\n const configExists = existsSync(configPath);\n const configContent = configExists ? readFileSync(configPath, 'utf-8') : undefined;\n\n // Load profile.json from the resolved data directory\n const profile = loadProfileConfig(dataDir);\n\n // --- Per-key priority ---\n // runtime keys: CLI flag > env var > config.yml > default\n // CLI-only keys: CLI flag > profile.json > env var\n\n // Network\n const cliNetwork = explicitFlags?.has('network')\n ? (process.env.FIBER_NETWORK as FiberNetwork | undefined)\n : undefined;\n const envNetwork = !explicitFlags?.has('network')\n ? (process.env.FIBER_NETWORK as FiberNetwork | undefined)\n : undefined;\n const fileNetwork = configContent ? parseNetworkFromConfig(configContent) : undefined;\n const network = cliNetwork || envNetwork || fileNetwork || DEFAULT_NETWORK;\n const networkSource: EffectiveConfigSources['network'] = cliNetwork\n ? 'cli'\n : envNetwork\n ? 'env'\n : fileNetwork\n ? 'config'\n : 'default';\n\n // RPC URL\n const cliRpcUrl = explicitFlags?.has('rpcUrl') ? process.env.FIBER_RPC_URL : undefined;\n const envRpcUrl = !explicitFlags?.has('rpcUrl') ? process.env.FIBER_RPC_URL : undefined;\n const fileRpcUrl = configContent ? parseRpcUrlFromConfig(configContent) : undefined;\n const rpcUrl = cliRpcUrl || envRpcUrl || fileRpcUrl || DEFAULT_RPC_URL;\n const rpcUrlSource: EffectiveConfigSources['rpcUrl'] = cliRpcUrl\n ? 'cli'\n : envRpcUrl\n ? 'env'\n : fileRpcUrl\n ? 'config'\n : 'default';\n\n // RPC Biscuit token (auth bearer token)\n const cliRpcBiscuitToken = explicitFlags?.has('rpcBiscuitToken')\n ? process.env.FIBER_RPC_BISCUIT_TOKEN\n : undefined;\n const envRpcBiscuitToken = !explicitFlags?.has('rpcBiscuitToken')\n ? process.env.FIBER_RPC_BISCUIT_TOKEN\n : undefined;\n const rpcBiscuitToken = cliRpcBiscuitToken || envRpcBiscuitToken || undefined;\n const rpcBiscuitTokenSource: EffectiveConfigSources['rpcBiscuitToken'] = cliRpcBiscuitToken\n ? 'cli'\n : envRpcBiscuitToken\n ? 'env'\n : 'unset';\n\n // Binary path\n const cliBinaryPath = explicitFlags?.has('binaryPath')\n ? process.env.FIBER_BINARY_PATH\n : undefined;\n const profileBinaryPath = profile?.binaryPath;\n const envBinaryPath = !explicitFlags?.has('binaryPath')\n ? process.env.FIBER_BINARY_PATH\n : undefined;\n const binaryPath = cliBinaryPath || profileBinaryPath || envBinaryPath || undefined;\n\n // Key password\n const cliKeyPassword = explicitFlags?.has('keyPassword')\n ? process.env.FIBER_KEY_PASSWORD\n : undefined;\n const profileKeyPassword = profile?.keyPassword;\n const envKeyPassword = !explicitFlags?.has('keyPassword')\n ? process.env.FIBER_KEY_PASSWORD\n : undefined;\n const keyPassword = cliKeyPassword || profileKeyPassword || envKeyPassword || undefined;\n\n // CKB RPC URL\n const envCkbRpcUrl = process.env.FIBER_CKB_RPC_URL;\n const fileCkbRpcUrl = configContent ? parseCkbRpcUrlFromConfig(configContent) : undefined;\n const ckbRpcUrl = envCkbRpcUrl || fileCkbRpcUrl || undefined;\n const ckbRpcUrlSource: EffectiveConfigSources['ckbRpcUrl'] = envCkbRpcUrl\n ? 'env'\n : fileCkbRpcUrl\n ? 'config'\n : 'unset';\n\n // Runtime proxy listen — CLI flag > env var > profile.json > default\n const DEFAULT_RUNTIME_PROXY_LISTEN = '127.0.0.1:8229';\n const cliRuntimeProxyListen = explicitFlags?.has('runtimeProxyListen')\n ? process.env.FIBER_RUNTIME_PROXY_LISTEN\n : undefined;\n const envRuntimeProxyListen = !explicitFlags?.has('runtimeProxyListen')\n ? process.env.FIBER_RUNTIME_PROXY_LISTEN\n : undefined;\n const profileRuntimeProxyListen = profile?.runtimeProxyListen;\n const runtimeProxyListen =\n cliRuntimeProxyListen ||\n envRuntimeProxyListen ||\n profileRuntimeProxyListen ||\n DEFAULT_RUNTIME_PROXY_LISTEN;\n const runtimeProxyListenSource: EffectiveConfigSources['runtimeProxyListen'] =\n cliRuntimeProxyListen\n ? 'cli'\n : envRuntimeProxyListen\n ? 'env'\n : profileRuntimeProxyListen\n ? 'profile'\n : 'default';\n\n return {\n configExists,\n config: {\n binaryPath,\n dataDir,\n configPath,\n network,\n rpcUrl,\n rpcBiscuitToken,\n keyPassword,\n ckbRpcUrl,\n runtimeProxyListen,\n },\n sources: {\n dataDir: dataDirSource,\n configPath: 'derived',\n network: networkSource,\n rpcUrl: rpcUrlSource,\n rpcBiscuitToken: rpcBiscuitTokenSource,\n ckbRpcUrl: ckbRpcUrlSource,\n runtimeProxyListen: runtimeProxyListenSource,\n },\n };\n}\n\nexport function getConfig(): CliConfig {\n return getEffectiveConfig().config;\n}\n","export type FiberNetwork = 'testnet' | 'mainnet';\n\nexport const TESTNET_CONFIG_TEMPLATE_V071 = `# This configuration file only contains the necessary configurations for the testnet deployment.\n# All options' descriptions can be found via \\`fnn --help\\` and be overridden by command line arguments or environment variables.\nfiber:\n listening_addr: \"/ip4/0.0.0.0/tcp/8228\"\n bootnode_addrs:\n - \"/ip4/54.179.226.154/tcp/8228/p2p/Qmes1EBD4yNo9Ywkfe6eRw9tG1nVNGLDmMud1xJMsoYFKy\"\n - \"/ip4/16.163.7.105/tcp/8228/p2p/QmdyQWjPtbK4NWWsvy8s69NGJaQULwgeQDT5ZpNDrTNaeV\"\n announce_listening_addr: true\n announced_addrs:\n # If you want to announce your fiber node public address to the network, you need to add the address here, please change the ip to your public ip accordingly.\n # - \"/ip4/YOUR-FIBER-NODE-PUBLIC-IP/tcp/8228\"\n chain: testnet\n # lock script configurations related to fiber network\n # https://github.com/nervosnetwork/fiber-scripts/blob/main/deployment/testnet/migrations/2025-02-28-111246.json\n scripts:\n - name: FundingLock\n script:\n code_hash: \"0x6c67887fe201ee0c7853f1682c0b77c0e6214044c156c7558269390a8afa6d7c\"\n hash_type: type\n args: \"0x\"\n cell_deps:\n - type_id:\n code_hash: \"0x00000000000000000000000000000000000000000000000000545950455f4944\"\n hash_type: type\n args: \"0x3cb7c0304fe53f75bb5727e2484d0beae4bd99d979813c6fc97c3cca569f10f6\"\n - cell_dep:\n out_point:\n tx_hash: \"0x12c569a258dd9c5bd99f632bb8314b1263b90921ba31496467580d6b79dd14a7\" # ckb_auth\n index: 0x0\n dep_type: code\n - name: CommitmentLock\n script:\n code_hash: \"0x740dee83f87c6f309824d8fd3fbdd3c8380ee6fc9acc90b1a748438afcdf81d8\"\n hash_type: type\n args: \"0x\"\n cell_deps:\n - type_id:\n code_hash: \"0x00000000000000000000000000000000000000000000000000545950455f4944\"\n hash_type: type\n args: \"0xf7e458887495cf70dd30d1543cad47dc1dfe9d874177bf19291e4db478d5751b\"\n - cell_dep:\n out_point:\n tx_hash: \"0x12c569a258dd9c5bd99f632bb8314b1263b90921ba31496467580d6b79dd14a7\" #ckb_auth\n index: 0x0\n dep_type: code\n\nrpc:\n # By default RPC only binds to localhost, thus it only allows accessing from the same machine.\n # Allowing arbitrary machines to access the JSON-RPC port is dangerous and strongly discouraged.\n # Please strictly limit the access to only trusted machines.\n listening_addr: \"127.0.0.1:8227\"\n\nckb:\n rpc_url: \"https://testnet.ckbapp.dev/\"\n udt_whitelist:\n - name: RUSD\n script:\n code_hash: \"0x1142755a044bf2ee358cba9f2da187ce928c91cd4dc8692ded0337efa677d21a\"\n hash_type: type\n args: \"0x878fcc6f1f08d48e87bb1c3b3d5083f23f8a39c5d5c764f253b55b998526439b\"\n cell_deps:\n - type_id:\n code_hash: \"0x00000000000000000000000000000000000000000000000000545950455f4944\"\n hash_type: type\n args: \"0x97d30b723c0b2c66e9cb8d4d0df4ab5d7222cbb00d4a9a2055ce2e5d7f0d8b0f\"\n auto_accept_amount: 1000000000\n\nservices:\n - fiber\n - rpc\n - ckb\n`;\n\nexport const MAINNET_CONFIG_TEMPLATE_V071 = `# This configuration file only contains the necessary configurations for the mainnet deployment.\n# All options' descriptions can be found via \\`fnn --help\\` and be overridden by command line arguments or environment variables.\nfiber:\n listening_addr: \"/ip4/0.0.0.0/tcp/8228\"\n bootnode_addrs:\n - \"/ip4/43.199.24.44/tcp/8228/p2p/QmZ2gCTfEF6vKsiYFF2STPeA2rRLRim9nMtzfwiE7uMQ4v\"\n - \"/ip4/54.255.71.126/tcp/8228/p2p/QmcMLnWraRyxd7PFRgvn1QeYRQS2DGsP6fPFCQjtfMs5b2\"\n announce_listening_addr: true\n announced_addrs:\n # If you want to announce your fiber node public address to the network, you need to add the address here.\n # Please change the ip to your public ip accordingly, and make sure the port is open and reachable from the internet.\n # - \"/ip4/YOUR-FIBER-NODE-PUBLIC-IP/tcp/8228\"\n chain: mainnet\n # lock script configurations related to fiber network\n # https://github.com/nervosnetwork/fiber-scripts/blob/main/deployment/mainnet/migrations/2025-02-28-114908.json\n scripts:\n - name: FundingLock\n script:\n code_hash: \"0xe45b1f8f21bff23137035a3ab751d75b36a981deec3e7820194b9c042967f4f1\"\n hash_type: type\n args: \"0x\"\n cell_deps:\n - type_id:\n code_hash: \"0x00000000000000000000000000000000000000000000000000545950455f4944\"\n hash_type: type\n args: \"0x64818d82a372312fb007c480391e1b9759d21b2c7f7959b9c177d72cdc243394\"\n - cell_dep:\n out_point:\n tx_hash: \"0x95006eee7b4c0c8ad66e0514c88ed0ae43fc8db27793427de86a348ec720b9d6\" # ckb_auth\n index: 0x0\n dep_type: code\n - name: CommitmentLock\n script:\n code_hash: \"0x2d45c4d3ed3e942f1945386ee82a5d1b7e4bb16d7fe1ab015421174ab747406c\"\n hash_type: type\n args: \"0x\"\n cell_deps:\n - type_id:\n code_hash: \"0x00000000000000000000000000000000000000000000000000545950455f4944\"\n hash_type: type\n args: \"0xdb16e6dcb17f670e5fb7c556d81e522ec5edb069ad2fa3e898e7ccea6c26a39f\"\n - cell_dep:\n out_point:\n tx_hash: \"0x95006eee7b4c0c8ad66e0514c88ed0ae43fc8db27793427de86a348ec720b9d6\" #ckb_auth\n index: 0x0\n dep_type: code\n\nrpc:\n # By default RPC only binds to localhost, thus it only allows accessing from the same machine.\n # Allowing arbitrary machines to access the JSON-RPC port is dangerous and strongly discouraged.\n # Please strictly limit the access to only trusted machines.\n listening_addr: \"127.0.0.1:8227\"\n\nckb:\n # Please use a trusted CKB RPC node, the node should be able to provide the correct data and should be stable.\n rpc_url: \"http://127.0.0.1:8114/\"\n udt_whitelist:\n ## https://github.com/CKBFansDAO/xudtlogos/blob/f2557839ecde0409ba674516a62ae6752bc0daa9/public/tokens/token_list.json#L548\n - name: USDI\n script:\n code_hash: \"0xbfa35a9c38a676682b65ade8f02be164d48632281477e36f8dc2f41f79e56bfc\"\n hash_type: type\n args: \"0xd591ebdc69626647e056e13345fd830c8b876bb06aa07ba610479eb77153ea9f\"\n cell_deps:\n - type_id:\n code_hash: \"0x00000000000000000000000000000000000000000000000000545950455f4944\"\n hash_type: type\n args: \"0x9105ea69838511ca609518d27855c53fed1b5ffaff4cfb334f58b40627d211c4\"\n auto_accept_amount: 10000000\n\nservices:\n - fiber\n - rpc\n - ckb\n`;\n\nexport function getConfigTemplate(network: FiberNetwork): string {\n return network === 'mainnet' ? MAINNET_CONFIG_TEMPLATE_V071 : TESTNET_CONFIG_TEMPLATE_V071;\n}\n","import type { GraphChannelInfo, GraphNodeInfo } from '@fiber-pay/sdk';\nimport { shannonsToCkb, toHex } from '@fiber-pay/sdk';\nimport { Command } from 'commander';\nimport type { CliConfig } from '../lib/config.js';\nimport { formatAge, parseHexTimestampMs, printJsonSuccess, truncateMiddle } from '../lib/format.js';\nimport { createReadyRpcClient } from '../lib/rpc.js';\n\nfunction printGraphNodeListHuman(nodes: GraphNodeInfo[]): void {\n if (nodes.length === 0) {\n console.log('No nodes found in the graph.');\n return;\n }\n\n console.log(`Graph Nodes: ${nodes.length}`);\n console.log('');\n console.log('NODE ID ALIAS VERSION MIN FUNDING AGE');\n console.log('---------------------------------------------------------------------------------');\n\n for (const node of nodes) {\n const nodeId = truncateMiddle(node.node_id, 10, 8).padEnd(22, ' ');\n const alias = (node.node_name || '(unnamed)').slice(0, 20).padEnd(20, ' ');\n const version = (node.version || '?').slice(0, 10).padEnd(10, ' ');\n const minFunding = shannonsToCkb(node.auto_accept_min_ckb_funding_amount)\n .toString()\n .padStart(12, ' ');\n const age = formatAge(parseHexTimestampMs(node.timestamp));\n console.log(`${nodeId} ${alias} ${version} ${minFunding} ${age}`);\n }\n}\n\nfunction printGraphChannelListHuman(channels: GraphChannelInfo[]): void {\n if (channels.length === 0) {\n console.log('No channels found in the graph.');\n return;\n }\n\n console.log(`Graph Channels: ${channels.length}`);\n console.log('');\n console.log(\n 'OUTPOINT NODE1 NODE2 CAPACITY AGE',\n );\n console.log(\n '----------------------------------------------------------------------------------------------',\n );\n\n for (const ch of channels) {\n const outpoint = ch.channel_outpoint\n ? truncateMiddle(`${ch.channel_outpoint.tx_hash}:${ch.channel_outpoint.index}`, 10, 8)\n : 'n/a';\n const n1 = truncateMiddle(ch.node1, 10, 8).padEnd(22, ' ');\n const n2 = truncateMiddle(ch.node2, 10, 8).padEnd(22, ' ');\n const capacity = `${shannonsToCkb(ch.capacity)} CKB`.padStart(12, ' ');\n const age = formatAge(parseHexTimestampMs(ch.created_timestamp));\n console.log(`${outpoint.padEnd(22, ' ')} ${n1} ${n2} ${capacity} ${age}`);\n }\n}\n\nexport function createGraphCommand(config: CliConfig): Command {\n const graph = new Command('graph').description('Network graph queries (nodes & channels)');\n\n graph\n .command('nodes')\n .option('--limit <n>', 'Maximum number of nodes to return', '50')\n .option('--after <cursor>', 'Pagination cursor from a previous query')\n .option('--json')\n .action(async (options) => {\n const rpc = await createReadyRpcClient(config);\n const limit = toHex(BigInt(parseInt(options.limit, 10)));\n const result = await rpc.graphNodes({\n limit,\n after: options.after,\n });\n\n if (options.json) {\n printJsonSuccess({ nodes: result.nodes, lastCursor: result.last_cursor });\n } else {\n printGraphNodeListHuman(result.nodes);\n if (result.last_cursor && result.last_cursor !== '0x0') {\n console.log(`\\nNext cursor: ${result.last_cursor}`);\n }\n }\n });\n\n graph\n .command('channels')\n .option('--limit <n>', 'Maximum number of channels to return', '50')\n .option('--after <cursor>', 'Pagination cursor from a previous query')\n .option('--json')\n .action(async (options) => {\n const rpc = await createReadyRpcClient(config);\n const limit = toHex(BigInt(parseInt(options.limit, 10)));\n const result = await rpc.graphChannels({\n limit,\n after: options.after,\n });\n\n if (options.json) {\n printJsonSuccess({ channels: result.channels, lastCursor: result.last_cursor });\n } else {\n printGraphChannelListHuman(result.channels);\n if (result.last_cursor && result.last_cursor !== '0x0') {\n console.log(`\\nNext cursor: ${result.last_cursor}`);\n }\n }\n });\n\n return graph;\n}\n","import { ckbToShannons, type HexString, randomBytes32, shannonsToCkb, toHex } from '@fiber-pay/sdk';\nimport { Command } from 'commander';\nimport type { CliConfig } from '../lib/config.js';\nimport {\n extractInvoiceMetadata,\n parseHexTimestampMs,\n printInvoiceDetailHuman,\n printJsonError,\n printJsonSuccess,\n} from '../lib/format.js';\nimport { createReadyRpcClient, resolveRpcEndpoint } from '../lib/rpc.js';\nimport { tryCreateRuntimeInvoiceJob, waitForRuntimeJobTerminal } from '../lib/runtime-jobs.js';\n\nexport function createInvoiceCommand(config: CliConfig): Command {\n const invoice = new Command('invoice').description('Invoice lifecycle and status commands');\n\n invoice\n .command('create')\n .argument('[amount]')\n .option('--amount <ckb>')\n .option('--description <text>')\n .option('--expiry <minutes>')\n .option('--json')\n .action(async (amountArg, options) => {\n const rpc = await createReadyRpcClient(config);\n const json = Boolean(options.json);\n\n const amountCkb = options.amount\n ? parseFloat(options.amount)\n : amountArg\n ? parseFloat(amountArg)\n : 0;\n if (!amountCkb) {\n if (options.json) {\n printJsonError({\n code: 'INVOICE_CREATE_INPUT_INVALID',\n message: 'Amount required. Usage: invoice create --amount <CKB>',\n recoverable: true,\n suggestion: 'Provide a valid positive amount via `--amount <CKB>`.',\n });\n } else {\n console.error('Error: Amount required. Usage: invoice create --amount <CKB>');\n }\n process.exit(1);\n }\n\n const expirySeconds = (options.expiry ? parseInt(options.expiry, 10) : 60) * 60;\n const currency = config.network === 'mainnet' ? 'Fibb' : 'Fibt';\n\n const endpoint = resolveRpcEndpoint(config);\n if (endpoint.target === 'runtime-proxy') {\n const created = await tryCreateRuntimeInvoiceJob(endpoint.url, {\n params: {\n action: 'create',\n newInvoiceParams: {\n amount: ckbToShannons(amountCkb),\n currency,\n description: options.description,\n expiry: toHex(expirySeconds),\n payment_preimage: randomBytes32(),\n },\n waitForTerminal: false,\n },\n });\n\n if (created) {\n const job = await waitForRuntimeJobTerminal(endpoint.url, created.id, 60);\n if (job.state !== 'succeeded') {\n throw new Error(job.error?.message ?? `Invoice create job ${job.state}`);\n }\n\n const result = (job.result ?? {}) as {\n invoiceAddress?: string;\n paymentHash?: string;\n status?: string;\n };\n\n const payload = {\n jobId: job.id,\n invoice: result.invoiceAddress,\n paymentHash: result.paymentHash,\n amountCkb,\n expiresAt: new Date(Date.now() + expirySeconds * 1000).toISOString(),\n status: (result.status ?? 'Open').toLowerCase(),\n };\n\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log('Invoice created');\n console.log(` Job: ${payload.jobId}`);\n console.log(` Payment Hash: ${payload.paymentHash ?? 'n/a'}`);\n console.log(` Amount: ${payload.amountCkb} CKB`);\n console.log(` Expires At: ${payload.expiresAt}`);\n console.log(` Invoice: ${payload.invoice ?? 'n/a'}`);\n }\n return;\n }\n }\n\n const result = await rpc.newInvoice({\n amount: ckbToShannons(amountCkb),\n currency,\n description: options.description,\n expiry: toHex(expirySeconds),\n payment_preimage: randomBytes32(),\n });\n\n const payload = {\n invoice: result.invoice_address,\n paymentHash: result.invoice.data.payment_hash,\n amountCkb,\n expiresAt: new Date(Date.now() + expirySeconds * 1000).toISOString(),\n status: 'open',\n };\n\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log('Invoice created');\n console.log(` Payment Hash: ${payload.paymentHash}`);\n console.log(` Amount: ${payload.amountCkb} CKB`);\n console.log(` Expires At: ${payload.expiresAt}`);\n console.log(` Invoice: ${payload.invoice}`);\n }\n });\n\n invoice\n .command('get')\n .argument('<paymentHash>')\n .option('--json')\n .action(async (paymentHash, options) => {\n const rpc = await createReadyRpcClient(config);\n const result = await rpc.getInvoice({ payment_hash: paymentHash as HexString });\n const metadata = extractInvoiceMetadata(result.invoice);\n const createdAtMs = parseHexTimestampMs(result.invoice.data.timestamp);\n const output = {\n paymentHash,\n status: result.status,\n invoice: result.invoice_address,\n amountCkb: result.invoice.amount ? shannonsToCkb(result.invoice.amount) : undefined,\n currency: result.invoice.currency,\n description: metadata.description,\n createdAt: createdAtMs\n ? new Date(createdAtMs).toISOString()\n : result.invoice.data.timestamp,\n expiresAt: metadata.expiresAt,\n age: metadata.age,\n };\n\n if (options.json) {\n printJsonSuccess(output);\n } else {\n printInvoiceDetailHuman(output);\n }\n });\n\n invoice\n .command('parse')\n .argument('<invoiceString>')\n .option('--json')\n .action(async (invoiceString, options) => {\n const rpc = await createReadyRpcClient(config);\n const result = await rpc.parseInvoice({ invoice: invoiceString });\n if (options.json) {\n printJsonSuccess(result);\n } else {\n console.log('Invoice parsed');\n console.log(JSON.stringify(result, null, 2));\n }\n });\n\n invoice\n .command('cancel')\n .argument('<paymentHash>')\n .option('--json')\n .action(async (paymentHash, options) => {\n const rpc = await createReadyRpcClient(config);\n const json = Boolean(options.json);\n\n const endpoint = resolveRpcEndpoint(config);\n if (endpoint.target === 'runtime-proxy') {\n const created = await tryCreateRuntimeInvoiceJob(endpoint.url, {\n params: {\n action: 'cancel',\n cancelInvoiceParams: { payment_hash: paymentHash as HexString },\n },\n options: {\n idempotencyKey: `invoice:cancel:${paymentHash}`,\n },\n });\n\n if (created) {\n const job = await waitForRuntimeJobTerminal(endpoint.url, created.id, 60);\n if (job.state !== 'succeeded') {\n throw new Error(job.error?.message ?? `Invoice cancel job ${job.state}`);\n }\n\n const result = (job.result ?? {}) as {\n status?: string;\n invoiceAddress?: string;\n };\n\n const output = {\n jobId: job.id,\n paymentHash,\n status: result.status ?? 'Cancelled',\n invoice: result.invoiceAddress,\n };\n\n if (json) {\n printJsonSuccess(output);\n } else {\n console.log('Invoice cancelled');\n console.log(` Job: ${output.jobId}`);\n console.log(` Payment Hash: ${output.paymentHash}`);\n console.log(` Status: ${output.status}`);\n console.log(` Invoice: ${output.invoice ?? 'n/a'}`);\n }\n return;\n }\n }\n\n const result = await rpc.cancelInvoice({ payment_hash: paymentHash as HexString });\n const output = { paymentHash, status: result.status, invoice: result.invoice_address };\n if (json) {\n printJsonSuccess(output);\n } else {\n console.log('Invoice cancelled');\n console.log(` Payment Hash: ${output.paymentHash}`);\n console.log(` Status: ${output.status}`);\n console.log(` Invoice: ${output.invoice}`);\n }\n });\n\n invoice\n .command('settle')\n .argument('<paymentHash>')\n .requiredOption('--preimage <preimage>')\n .option('--json')\n .action(async (paymentHash, options) => {\n const rpc = await createReadyRpcClient(config);\n const json = Boolean(options.json);\n\n const endpoint = resolveRpcEndpoint(config);\n if (endpoint.target === 'runtime-proxy') {\n const created = await tryCreateRuntimeInvoiceJob(endpoint.url, {\n params: {\n action: 'settle',\n settleInvoiceParams: {\n payment_hash: paymentHash as HexString,\n payment_preimage: options.preimage as HexString,\n },\n },\n options: {\n idempotencyKey: `invoice:settle:${paymentHash}`,\n },\n });\n\n if (created) {\n const job = await waitForRuntimeJobTerminal(endpoint.url, created.id, 60);\n if (job.state !== 'succeeded') {\n throw new Error(job.error?.message ?? `Invoice settle job ${job.state}`);\n }\n\n const output = { jobId: job.id, paymentHash, message: 'Invoice settled.' };\n if (json) {\n printJsonSuccess(output);\n } else {\n console.log(output.message);\n console.log(` Job: ${output.jobId}`);\n console.log(` Payment Hash: ${output.paymentHash}`);\n }\n return;\n }\n }\n\n await rpc.settleInvoice({\n payment_hash: paymentHash as HexString,\n payment_preimage: options.preimage as HexString,\n });\n\n if (json) {\n printJsonSuccess({ paymentHash, message: 'Invoice settled.' });\n } else {\n console.log('Invoice settled');\n console.log(` Payment Hash: ${paymentHash}`);\n }\n });\n\n return invoice;\n}\n","import { existsSync } from 'node:fs';\nimport { Command } from 'commander';\nimport type { CliConfig } from '../lib/config.js';\nimport { printJsonError, printJsonSuccess } from '../lib/format.js';\nimport { readLastLines, resolvePersistedLogPaths } from '../lib/log-files.js';\nimport { resolveRpcEndpoint } from '../lib/rpc.js';\nimport type { RuntimeJobEventRecord, RuntimeJobRecord } from '../lib/runtime-jobs.js';\nimport { readRuntimeMeta } from '../lib/runtime-meta.js';\n\nexport function createJobCommand(config: CliConfig): Command {\n const job = new Command('job').description('Runtime job management commands');\n\n job\n .command('list')\n .option('--state <state>', 'Filter by job state')\n .option('--type <type>', 'Filter by job type (payment|invoice|channel)')\n .option('--limit <n>', 'Limit number of jobs')\n .option('--offset <n>', 'Offset for pagination')\n .option('--json')\n .action(async (options) => {\n const json = Boolean(options.json);\n const runtimeUrl = getRuntimeUrlOrExit(config, json);\n const query = new URLSearchParams();\n if (options.state) query.set('state', String(options.state));\n if (options.type) query.set('type', String(options.type));\n if (options.limit) query.set('limit', String(options.limit));\n if (options.offset) query.set('offset', String(options.offset));\n\n const response = await fetch(\n `${runtimeUrl}/jobs${query.toString() ? `?${query.toString()}` : ''}`,\n );\n if (!response.ok) {\n return handleHttpError(response, 'JOB_LIST_FAILED', json);\n }\n\n const payload = (await response.json()) as { jobs: RuntimeJobRecord[] };\n if (json) {\n printJsonSuccess(payload);\n return;\n }\n\n if (!payload.jobs.length) {\n console.log('No jobs found.');\n return;\n }\n\n console.log(`Jobs (${payload.jobs.length})`);\n for (const item of payload.jobs) {\n console.log(`- ${item.id}`);\n console.log(` Type: ${item.type}`);\n console.log(` State: ${item.state}`);\n if (item.idempotencyKey) console.log(` Key: ${item.idempotencyKey}`);\n if (typeof item.retryCount === 'number' && typeof item.maxRetries === 'number') {\n console.log(` Retry: ${item.retryCount}/${item.maxRetries}`);\n }\n }\n });\n\n job\n .command('get')\n .argument('<jobId>')\n .option('--json')\n .action(async (jobId, options) => {\n const json = Boolean(options.json);\n const runtimeUrl = getRuntimeUrlOrExit(config, json);\n const response = await fetch(`${runtimeUrl}/jobs/${jobId}`);\n if (!response.ok) {\n return handleHttpError(response, 'JOB_GET_FAILED', json);\n }\n\n const payload = (await response.json()) as RuntimeJobRecord;\n if (json) {\n printJsonSuccess(payload);\n return;\n }\n\n console.log('Job');\n console.log(` ID: ${payload.id}`);\n console.log(` Type: ${payload.type}`);\n console.log(` State: ${payload.state}`);\n if (payload.idempotencyKey) console.log(` Key: ${payload.idempotencyKey}`);\n if (typeof payload.retryCount === 'number' && typeof payload.maxRetries === 'number') {\n console.log(` Retry: ${payload.retryCount}/${payload.maxRetries}`);\n }\n if (payload.error?.message) {\n console.log(` Error: ${payload.error.message}`);\n }\n if (payload.result) {\n console.log(' Result:');\n console.log(` ${JSON.stringify(payload.result)}`);\n }\n });\n\n job\n .command('trace')\n .argument('<jobId>')\n .option('--tail <n>', 'Max lines to inspect per log file', '400')\n .option('--date <YYYY-MM-DD>', 'Date of log directory to search (default: today UTC)')\n .option('--json')\n .action(async (jobId, options) => {\n const json = Boolean(options.json);\n const tailInput = Number.parseInt(String(options.tail ?? '400'), 10);\n const tail = Number.isFinite(tailInput) && tailInput > 0 ? tailInput : 400;\n const date = options.date ? String(options.date).trim() : undefined;\n\n const runtimeUrl = getRuntimeUrlOrExit(config, json);\n const jobResponse = await fetch(`${runtimeUrl}/jobs/${jobId}`);\n if (!jobResponse.ok) {\n return handleHttpError(jobResponse, 'JOB_TRACE_GET_FAILED', json);\n }\n\n const eventsResponse = await fetch(`${runtimeUrl}/jobs/${jobId}/events`);\n if (!eventsResponse.ok) {\n return handleHttpError(eventsResponse, 'JOB_TRACE_EVENTS_FAILED', json);\n }\n\n const jobRecord = (await jobResponse.json()) as RuntimeJobRecord;\n const eventsPayload = (await eventsResponse.json()) as { events: RuntimeJobEventRecord[] };\n const tokens = collectTraceTokens(jobRecord, eventsPayload.events);\n\n const meta = readRuntimeMeta(config.dataDir);\n let logPaths: ReturnType<typeof resolvePersistedLogPaths>;\n try {\n logPaths = resolvePersistedLogPaths(config.dataDir, meta, date);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Invalid --date value.';\n if (json) {\n printJsonError({\n code: 'JOB_TRACE_DATE_INVALID',\n message,\n recoverable: true,\n suggestion: 'Retry with --date in YYYY-MM-DD format.',\n details: { date },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n const runtimeAlertMatches = collectRelatedLines(logPaths.runtimeAlerts, tokens, tail);\n const fnnStdoutMatches = collectRelatedLines(logPaths.fnnStdout, tokens, tail);\n const fnnStderrMatches = collectRelatedLines(logPaths.fnnStderr, tokens, tail);\n\n const result = {\n job: jobRecord,\n events: eventsPayload.events,\n trace: {\n tokens,\n logPaths,\n matches: {\n runtimeAlerts: runtimeAlertMatches,\n fnnStdout: fnnStdoutMatches,\n fnnStderr: fnnStderrMatches,\n },\n },\n };\n\n if (json) {\n printJsonSuccess(result);\n return;\n }\n\n console.log('Job trace');\n console.log(` Job ID: ${jobRecord.id}`);\n console.log(` Type: ${jobRecord.type}`);\n console.log(` State: ${jobRecord.state}`);\n if (jobRecord.idempotencyKey) {\n console.log(` Idempotency: ${jobRecord.idempotencyKey}`);\n }\n if (jobRecord.error?.message) {\n console.log(` Error: ${jobRecord.error.message}`);\n }\n console.log(` Events: ${eventsPayload.events.length}`);\n\n if (tokens.length > 0) {\n console.log(' Tokens:');\n for (const token of tokens) {\n console.log(` - ${token}`);\n }\n }\n\n printTraceSection('runtime.alerts', logPaths.runtimeAlerts, runtimeAlertMatches);\n printTraceSection('fnn.stdout', logPaths.fnnStdout, fnnStdoutMatches);\n printTraceSection('fnn.stderr', logPaths.fnnStderr, fnnStderrMatches);\n });\n\n job\n .command('events')\n .argument('<jobId>')\n .option('--with-data', 'Include event data payload in human-readable output')\n .option('--json')\n .action(async (jobId, options) => {\n const json = Boolean(options.json);\n const runtimeUrl = getRuntimeUrlOrExit(config, json);\n const response = await fetch(`${runtimeUrl}/jobs/${jobId}/events`);\n if (!response.ok) {\n return handleHttpError(response, 'JOB_EVENTS_FAILED', json);\n }\n\n const payload = (await response.json()) as { events: RuntimeJobEventRecord[] };\n if (json) {\n printJsonSuccess(payload);\n return;\n }\n\n if (!payload.events.length) {\n console.log('No events found for job.');\n return;\n }\n\n console.log(`Job events (${payload.events.length})`);\n for (const event of payload.events) {\n const timestamp = new Date(event.createdAt).toISOString();\n const transition = event.toState\n ? `${event.fromState ?? '(none)'} -> ${event.toState}`\n : (event.fromState ?? '(none)');\n console.log(`- ${timestamp} ${event.eventType} (${transition})`);\n if (options.withData && event.data !== undefined) {\n console.log(` data: ${JSON.stringify(event.data)}`);\n }\n }\n });\n\n job\n .command('cancel')\n .argument('<jobId>')\n .option('--json')\n .action(async (jobId, options) => {\n const json = Boolean(options.json);\n const runtimeUrl = getRuntimeUrlOrExit(config, json);\n const response = await fetch(`${runtimeUrl}/jobs/${jobId}`, { method: 'DELETE' });\n if (!response.ok) {\n return handleHttpError(response, 'JOB_CANCEL_FAILED', json);\n }\n\n const payload = { jobId, cancelled: true };\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log(`Job cancelled: ${jobId}`);\n }\n });\n\n return job;\n}\n\nfunction getRuntimeUrlOrExit(config: CliConfig, json: boolean): string {\n const endpoint = resolveRpcEndpoint(config);\n if (endpoint.target !== 'runtime-proxy') {\n const message =\n 'Runtime proxy is not active for the current profile/RPC URL. Start runtime first (fiber-pay runtime start --daemon).';\n if (json) {\n printJsonError({\n code: 'RUNTIME_PROXY_REQUIRED',\n message,\n recoverable: true,\n suggestion: 'Start runtime and retry the job command.',\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n return endpoint.url;\n}\n\nasync function handleHttpError(response: Response, code: string, json: boolean): Promise<never> {\n const body = await safeJson(response);\n const message = extractErrorMessage(body) ?? `HTTP ${response.status}`;\n\n if (json) {\n printJsonError({\n code,\n message,\n recoverable: response.status >= 500 || response.status === 404,\n suggestion: 'Check runtime status and job id, then retry.',\n details: {\n status: response.status,\n body,\n },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n}\n\nfunction extractErrorMessage(body: unknown): string | undefined {\n if (!body || typeof body !== 'object') {\n return undefined;\n }\n\n if ('error' in body) {\n const error = (body as { error?: unknown }).error;\n if (typeof error === 'string') {\n return error;\n }\n if (error && typeof error === 'object' && 'message' in error) {\n const message = (error as { message?: unknown }).message;\n if (typeof message === 'string') {\n return message;\n }\n }\n }\n\n if ('message' in body) {\n const message = (body as { message?: unknown }).message;\n if (typeof message === 'string') {\n return message;\n }\n }\n\n return undefined;\n}\n\nasync function safeJson(response: Response): Promise<unknown> {\n try {\n return await response.json();\n } catch {\n return undefined;\n }\n}\n\nfunction collectTraceTokens(job: RuntimeJobRecord, events: RuntimeJobEventRecord[]): string[] {\n const result = new Set<string>();\n addTraceToken(result, job.id);\n addTraceToken(result, job.idempotencyKey);\n\n collectStructuredTokens(result, job.params);\n collectStructuredTokens(result, job.result);\n collectStructuredTokens(result, job.error);\n\n for (const event of events) {\n addTraceToken(result, event.id);\n collectStructuredTokens(result, event.data);\n }\n\n return Array.from(result).slice(0, 20);\n}\n\nfunction addTraceToken(set: Set<string>, value: unknown): void {\n if (typeof value !== 'string') {\n return;\n }\n const normalized = value.trim();\n if (!normalized || normalized.length < 6) {\n return;\n }\n if (normalized.includes(' ')) {\n return;\n }\n if (normalized.length <= 128) {\n set.add(normalized);\n }\n}\n\nfunction collectStructuredTokens(set: Set<string>, input: unknown, depth = 0): void {\n if (depth > 3 || input === null || input === undefined) {\n return;\n }\n if (typeof input === 'string') {\n if (input.startsWith('0x') || input.includes('peer') || input.includes('channel')) {\n addTraceToken(set, input);\n }\n return;\n }\n if (Array.isArray(input)) {\n for (const item of input) {\n collectStructuredTokens(set, item, depth + 1);\n }\n return;\n }\n if (typeof input === 'object') {\n for (const value of Object.values(input as Record<string, unknown>)) {\n collectStructuredTokens(set, value, depth + 1);\n }\n }\n}\n\nfunction collectRelatedLines(filePath: string, tokens: string[], tail: number): string[] {\n if (!existsSync(filePath)) {\n return [];\n }\n const lines = readLastLines(filePath, tail);\n if (tokens.length === 0) {\n return lines.slice(-Math.min(30, lines.length));\n }\n\n const related = lines.filter((line) => tokens.some((token) => line.includes(token)));\n if (related.length > 0) {\n return related.slice(-Math.min(80, related.length));\n }\n\n return lines.slice(-Math.min(20, lines.length));\n}\n\nfunction printTraceSection(title: string, filePath: string, lines: string[]): void {\n console.log(`\\n${title}: ${filePath}`);\n if (!existsSync(filePath)) {\n console.log(' (file not found)');\n return;\n }\n if (lines.length === 0) {\n console.log(' (no related lines)');\n return;\n }\n for (const line of lines.slice(-20)) {\n console.log(` ${line}`);\n }\n}\n","import {\n appendFileSync,\n closeSync,\n createReadStream,\n existsSync,\n mkdirSync,\n openSync,\n readdirSync,\n readSync,\n statSync,\n} from 'node:fs';\nimport { join } from 'node:path';\nimport type { RuntimeMeta } from './runtime-meta.js';\n\nexport interface PersistedLogPaths {\n runtimeAlerts: string;\n fnnStdout: string;\n fnnStderr: string;\n}\n\nexport type PersistedLogSource = 'runtime' | 'fnn-stdout' | 'fnn-stderr';\nexport type PersistedLogSourceOption = PersistedLogSource | 'all';\n\nexport interface PersistedLogTarget {\n source: PersistedLogSource;\n title: 'runtime.alerts' | 'fnn.stdout' | 'fnn.stderr';\n path: string;\n}\n\nconst DATE_DIR_PATTERN = /^\\d{4}-\\d{2}-\\d{2}$/;\n\n/**\n * Returns the current UTC date as YYYY-MM-DD string.\n */\nexport function todayDateString(): string {\n const now = new Date();\n const y = now.getUTCFullYear();\n const m = String(now.getUTCMonth() + 1).padStart(2, '0');\n const d = String(now.getUTCDate()).padStart(2, '0');\n return `${y}-${m}-${d}`;\n}\n\nexport interface ResolveLogDirOptions {\n logsBaseDir?: string;\n ensureExists?: boolean;\n}\n\nexport function validateLogDate(date: string): string {\n const value = date.trim();\n if (!DATE_DIR_PATTERN.test(value)) {\n throw new Error(`Invalid date '${value}'. Expected format YYYY-MM-DD.`);\n }\n if (value.includes('/') || value.includes('\\\\') || value.includes('..')) {\n throw new Error(`Invalid date '${value}'. Path separators or '..' are not allowed.`);\n }\n return value;\n}\n\n/**\n * Returns the path to a date-based log directory: `<data-dir>/logs/<YYYY-MM-DD>/`.\n * Creates the directory if it does not exist.\n */\nexport function resolveLogDirForDate(dataDir: string, date?: string): string {\n return resolveLogDirForDateWithOptions(dataDir, date, {});\n}\n\nexport function resolveLogDirForDateWithOptions(\n dataDir: string,\n date: string | undefined,\n options: ResolveLogDirOptions,\n): string {\n const dateStr = date ?? todayDateString();\n const logsBaseDir = options.logsBaseDir ?? join(dataDir, 'logs');\n if (date !== undefined) {\n validateLogDate(dateStr);\n }\n const dir = join(logsBaseDir, dateStr);\n const ensureExists = options.ensureExists ?? true;\n if (ensureExists) {\n mkdirSync(dir, { recursive: true });\n }\n return dir;\n}\n\n/**\n * Resolve persisted log paths for a given date.\n *\n * When `date` is provided, always returns paths under `<data-dir>/logs/<date>/`.\n * When `date` is omitted and `meta` provides explicit paths, those are used for\n * backward compatibility. Otherwise defaults to today's date directory.\n */\nexport function resolvePersistedLogPaths(\n dataDir: string,\n meta?: RuntimeMeta | null,\n date?: string,\n): PersistedLogPaths {\n const logsBaseDir = meta?.logsBaseDir ?? join(dataDir, 'logs');\n\n if (date) {\n const dir = resolveLogDirForDateWithOptions(dataDir, date, {\n logsBaseDir,\n ensureExists: false,\n });\n return {\n runtimeAlerts: join(dir, 'runtime.alerts.jsonl'),\n fnnStdout: join(dir, 'fnn.stdout.log'),\n fnnStderr: join(dir, 'fnn.stderr.log'),\n };\n }\n\n if (meta?.alertLogFilePath || meta?.fnnStdoutLogPath || meta?.fnnStderrLogPath) {\n const defaultDir = resolveLogDirForDateWithOptions(dataDir, undefined, {\n logsBaseDir,\n ensureExists: false,\n });\n return {\n runtimeAlerts: meta.alertLogFilePath ?? join(defaultDir, 'runtime.alerts.jsonl'),\n fnnStdout: meta.fnnStdoutLogPath ?? join(defaultDir, 'fnn.stdout.log'),\n fnnStderr: meta.fnnStderrLogPath ?? join(defaultDir, 'fnn.stderr.log'),\n };\n }\n\n const dir = resolveLogDirForDateWithOptions(dataDir, undefined, {\n logsBaseDir,\n ensureExists: false,\n });\n return {\n runtimeAlerts: join(dir, 'runtime.alerts.jsonl'),\n fnnStdout: join(dir, 'fnn.stdout.log'),\n fnnStderr: join(dir, 'fnn.stderr.log'),\n };\n}\n\n/**\n * List available log dates by scanning `<data-dir>/logs/` for YYYY-MM-DD directories.\n * Returns date strings sorted newest-first.\n */\nexport function listLogDates(dataDir: string, logsBaseDir?: string): string[] {\n const logsDir = logsBaseDir ?? join(dataDir, 'logs');\n if (!existsSync(logsDir)) {\n return [];\n }\n\n const entries = readdirSync(logsDir, { withFileTypes: true });\n const dates = entries\n .filter((entry) => entry.isDirectory() && DATE_DIR_PATTERN.test(entry.name))\n .map((entry) => entry.name);\n\n dates.sort((a, b) => (a > b ? -1 : a < b ? 1 : 0));\n return dates;\n}\n\n/**\n * Append text to a log file inside today's date directory.\n * Creates the date directory on first write each day.\n */\nexport function appendToTodayLog(dataDir: string, filename: string, text: string): void {\n const dir = resolveLogDirForDate(dataDir);\n appendFileSync(join(dir, filename), text, 'utf-8');\n}\n\nexport function resolvePersistedLogTargets(\n paths: PersistedLogPaths,\n source: PersistedLogSourceOption,\n): PersistedLogTarget[] {\n const all: PersistedLogTarget[] = [\n {\n source: 'runtime',\n title: 'runtime.alerts',\n path: paths.runtimeAlerts,\n },\n {\n source: 'fnn-stdout',\n title: 'fnn.stdout',\n path: paths.fnnStdout,\n },\n {\n source: 'fnn-stderr',\n title: 'fnn.stderr',\n path: paths.fnnStderr,\n },\n ];\n\n if (source === 'all') {\n return all;\n }\n\n return all.filter((target) => target.source === source);\n}\n\nexport function readLastLines(filePath: string, maxLines: number): string[] {\n if (!existsSync(filePath)) {\n return [];\n }\n\n if (!Number.isFinite(maxLines) || maxLines <= 0) {\n return [];\n }\n\n let fd: number | undefined;\n try {\n fd = openSync(filePath, 'r');\n const size = statSync(filePath).size;\n if (size <= 0) {\n return [];\n }\n\n const chunkSize = 64 * 1024;\n let position = size;\n const chunks: string[] = [];\n let newlineCount = 0;\n\n while (position > 0 && newlineCount <= maxLines) {\n const start = Math.max(0, position - chunkSize);\n const bytesToRead = position - start;\n const buffer = Buffer.alloc(bytesToRead);\n const bytesRead = readSync(fd, buffer, 0, bytesToRead, start);\n const chunk = buffer.toString('utf8', 0, bytesRead);\n chunks.unshift(chunk);\n\n for (let index = 0; index < chunk.length; index += 1) {\n if (chunk.charCodeAt(index) === 10) {\n newlineCount += 1;\n }\n }\n\n position = start;\n }\n\n const content = chunks.join('');\n const lines = content.split(/\\r?\\n/).filter((line) => line.length > 0);\n return lines.slice(-maxLines);\n } finally {\n if (fd !== undefined) {\n try {\n closeSync(fd);\n } catch {\n // ignore close errors\n }\n }\n }\n}\n\nexport interface ReadAppendedLinesResult {\n lines: string[];\n nextOffset: number;\n remainder: string;\n}\n\nexport async function readAppendedLines(\n filePath: string,\n offset: number,\n remainder = '',\n): Promise<ReadAppendedLinesResult> {\n if (!existsSync(filePath)) {\n return { lines: [], nextOffset: 0, remainder: '' };\n }\n\n const size = statSync(filePath).size;\n const safeOffset = size < offset ? 0 : offset;\n if (safeOffset >= size) {\n return { lines: [], nextOffset: size, remainder };\n }\n\n const stream = createReadStream(filePath, {\n encoding: 'utf8',\n start: safeOffset,\n end: size - 1,\n });\n\n const lines: string[] = [];\n let pending = remainder;\n let bytesReadTotal = 0;\n\n for await (const chunk of stream) {\n const chunkText = String(chunk);\n bytesReadTotal += Buffer.byteLength(chunkText, 'utf8');\n\n const merged = `${pending}${chunkText}`;\n const parts = merged.split(/\\r?\\n/);\n pending = parts.pop() ?? '';\n\n for (const line of parts) {\n if (line.length > 0) {\n lines.push(line);\n }\n }\n }\n\n return {\n lines,\n nextOffset: safeOffset + bytesReadTotal,\n remainder: pending,\n };\n}\n","import { existsSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { type Alert, formatRuntimeAlert } from '@fiber-pay/runtime';\nimport { Command } from 'commander';\nimport type { CliConfig } from '../lib/config.js';\nimport { printJsonError, printJsonSuccess } from '../lib/format.js';\nimport {\n listLogDates,\n type PersistedLogSourceOption,\n readAppendedLines,\n readLastLines,\n resolvePersistedLogPaths,\n resolvePersistedLogTargets,\n} from '../lib/log-files.js';\nimport { readRuntimeMeta } from '../lib/runtime-meta.js';\n\nconst ALLOWED_SOURCES = new Set<PersistedLogSourceOption>([\n 'all',\n 'runtime',\n 'fnn-stdout',\n 'fnn-stderr',\n]);\nconst DATE_DIR_PATTERN = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nfunction parseRuntimeAlertLine(line: string): Alert | null {\n try {\n const parsed = JSON.parse(line) as Alert;\n if (!parsed || typeof parsed !== 'object') {\n return null;\n }\n return parsed;\n } catch {\n return null;\n }\n}\n\nfunction formatRuntimeAlertHuman(line: string): string {\n const parsed = parseRuntimeAlertLine(line);\n if (!parsed) {\n return line;\n }\n\n return formatRuntimeAlert(parsed);\n}\n\nfunction coerceJsonLineForOutput(source: PersistedLogSourceOption, line: string): unknown {\n if (source !== 'runtime') {\n return line;\n }\n return parseRuntimeAlertLine(line) ?? line;\n}\n\nexport function createLogsCommand(config: CliConfig): Command {\n return new Command('logs')\n .alias('log')\n .description('View persisted runtime/fnn logs')\n .option('--source <source>', 'Log source: all|runtime|fnn-stdout|fnn-stderr', 'all')\n .option('--tail <n>', 'Number of recent lines per source', '80')\n .option('--date <YYYY-MM-DD>', 'Date of log directory to read (default: today UTC)')\n .option('--list-dates', 'List available log dates and exit')\n .option('--follow', 'Keep streaming appended log lines (human output mode only)')\n .option('--interval-ms <ms>', 'Polling interval for --follow mode', '1000')\n .option('--json')\n .action(async (options) => {\n const json = Boolean(options.json);\n const follow = Boolean(options.follow);\n const listDates = Boolean(options.listDates);\n const date = options.date ? String(options.date).trim() : undefined;\n const meta = readRuntimeMeta(config.dataDir);\n\n if (follow && date) {\n const message = \"--follow cannot be used with --date. --follow only streams today's logs.\";\n if (json) {\n printJsonError({\n code: 'LOG_FOLLOW_DATE_UNSUPPORTED',\n message,\n recoverable: true,\n suggestion: 'Remove --date or remove --follow and retry.',\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n\n // --list-dates mode: show available log dates and exit\n if (listDates) {\n const logsDir = meta?.logsBaseDir ?? join(config.dataDir, 'logs');\n const dates = listLogDates(config.dataDir, logsDir);\n if (json) {\n printJsonSuccess({ dates, logsDir });\n } else {\n if (dates.length === 0) {\n console.log('No log dates found.');\n } else {\n console.log(`Log dates (${dates.length}):`);\n for (const date of dates) {\n console.log(` ${date}`);\n }\n console.log(`\\nLogs directory: ${logsDir}`);\n }\n }\n return;\n }\n\n const sourceInput = String(options.source ?? 'all')\n .trim()\n .toLowerCase();\n\n if (json && follow) {\n const message = '--follow is not supported with --json. Use human mode for streaming logs.';\n printJsonError({\n code: 'LOG_FOLLOW_JSON_UNSUPPORTED',\n message,\n recoverable: true,\n suggestion: 'Remove --json or remove --follow and retry.',\n });\n process.exit(1);\n }\n\n if (!ALLOWED_SOURCES.has(sourceInput as PersistedLogSourceOption)) {\n const message =\n 'Invalid --source value. Expected one of: all, runtime, fnn-stdout, fnn-stderr.';\n if (json) {\n printJsonError({\n code: 'LOG_SOURCE_INVALID',\n message,\n recoverable: true,\n suggestion: 'Retry with --source all|runtime|fnn-stdout|fnn-stderr.',\n details: { source: sourceInput },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n\n const source = sourceInput as PersistedLogSourceOption;\n const tailInput = Number.parseInt(String(options.tail ?? '80'), 10);\n const tail = Number.isFinite(tailInput) && tailInput > 0 ? tailInput : 80;\n const intervalInput = Number.parseInt(String(options.intervalMs ?? '1000'), 10);\n const intervalMs = Number.isFinite(intervalInput) && intervalInput > 0 ? intervalInput : 1000;\n\n let paths: ReturnType<typeof resolvePersistedLogPaths>;\n try {\n paths = resolvePersistedLogPaths(config.dataDir, meta, date);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Invalid --date value.';\n if (json) {\n printJsonError({\n code: 'LOG_DATE_INVALID',\n message,\n recoverable: true,\n suggestion: 'Retry with --date in YYYY-MM-DD format.',\n details: { date },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n\n const targets = resolvePersistedLogTargets(paths, source);\n const displayDate = date ?? inferDateFromPaths(paths);\n\n if (source !== 'all' && targets.length === 1 && !existsSync(targets[0].path)) {\n const dateLabel = displayDate ? ` on ${displayDate}` : '';\n const message = `Log file not found for source ${source}${dateLabel}: ${targets[0].path}`;\n if (json) {\n printJsonError({\n code: 'LOG_FILE_NOT_FOUND',\n message,\n recoverable: true,\n suggestion:\n 'Start node/runtime or generate activity, then retry logs command. Use --list-dates to see available dates.',\n details: { source, date: displayDate ?? null, path: targets[0].path },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n\n const entries = [] as Array<{\n source: (typeof targets)[number]['source'];\n title: (typeof targets)[number]['title'];\n path: string;\n exists: boolean;\n lineCount: number;\n lines: string[];\n jsonLines: unknown[];\n }>;\n\n for (const target of targets) {\n const exists = existsSync(target.path);\n let lines: string[] = [];\n if (exists) {\n try {\n lines = readLastLines(target.path, tail);\n } catch (error) {\n const message =\n error instanceof Error ? error.message : `Failed to read log file: ${target.path}`;\n if (json) {\n printJsonError({\n code: 'LOG_READ_FAILED',\n message,\n recoverable: true,\n suggestion: 'Check log file permissions and retry.',\n details: { source: target.source, path: target.path },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n }\n\n entries.push({\n source: target.source,\n title: target.title,\n path: target.path,\n exists,\n lineCount: lines.length,\n lines,\n jsonLines: lines.map((line) => coerceJsonLineForOutput(target.source, line)),\n });\n }\n\n if (json) {\n printJsonSuccess({\n source,\n tail,\n date: displayDate ?? null,\n entries: entries.map((entry) => ({\n source: entry.source,\n title: entry.title,\n path: entry.path,\n exists: entry.exists,\n lineCount: entry.lineCount,\n lines: entry.jsonLines,\n })),\n });\n return;\n }\n\n const headerDate = displayDate ? `, date: ${displayDate}` : '';\n console.log(`Logs (source: ${source}${headerDate}, tail: ${tail})`);\n for (const entry of entries) {\n console.log(`\\n${entry.title}: ${entry.path}`);\n if (!entry.exists) {\n console.log(' (file not found)');\n continue;\n }\n if (entry.lines.length === 0) {\n console.log(' (no lines)');\n continue;\n }\n for (const line of entry.lines) {\n const output = entry.source === 'runtime' ? formatRuntimeAlertHuman(line) : line;\n console.log(` ${output}`);\n }\n }\n\n if (!follow) {\n return;\n }\n\n console.log(`\\nFollowing logs (interval: ${intervalMs}ms). Press Ctrl+C to stop.`);\n\n const states = new Map(\n entries.map((entry) => [\n entry.source,\n {\n title: entry.title,\n path: entry.path,\n offset: entry.exists ? statSync(entry.path).size : 0,\n remainder: '',\n },\n ]),\n );\n\n // Keep process alive for follow mode.\n await new Promise<void>((resolve) => {\n let stopped = false;\n const stop = () => {\n if (stopped) return;\n stopped = true;\n clearInterval(timer);\n process.off('SIGINT', stop);\n process.off('SIGTERM', stop);\n console.log('\\nStopped following logs.');\n resolve();\n };\n\n let polling = false;\n const timer = setInterval(() => {\n if (polling) {\n return;\n }\n polling = true;\n\n void (async () => {\n for (const target of targets) {\n const state = states.get(target.source);\n if (!state) continue;\n\n if (!existsSync(state.path)) {\n state.offset = 0;\n state.remainder = '';\n continue;\n }\n\n const result = await readAppendedLines(state.path, state.offset, state.remainder);\n const newLines = result.lines;\n if (newLines.length === 0) {\n state.offset = result.nextOffset;\n state.remainder = result.remainder;\n continue;\n }\n\n for (const line of newLines) {\n const output = target.source === 'runtime' ? formatRuntimeAlertHuman(line) : line;\n console.log(`[${state.title}] ${output}`);\n }\n state.offset = result.nextOffset;\n state.remainder = result.remainder;\n }\n })()\n .catch((error) => {\n const message =\n error instanceof Error ? error.message : 'Failed to read appended logs';\n console.error(`Error: ${message}`);\n })\n .finally(() => {\n polling = false;\n });\n }, intervalMs);\n\n process.on('SIGINT', stop);\n process.on('SIGTERM', stop);\n });\n });\n}\n\nfunction inferDateFromPaths(paths: {\n runtimeAlerts: string;\n fnnStdout: string;\n fnnStderr: string;\n}): string | undefined {\n const candidate = paths.runtimeAlerts.split('/').at(-2);\n if (!candidate || !DATE_DIR_PATTERN.test(candidate)) {\n return undefined;\n }\n\n const stdoutDate = paths.fnnStdout.split('/').at(-2);\n const stderrDate = paths.fnnStderr.split('/').at(-2);\n if (stdoutDate !== candidate || stderrDate !== candidate) {\n return undefined;\n }\n\n return candidate;\n}\n","import { Command } from 'commander';\nimport type { CliConfig } from '../lib/config.js';\nimport { runNodeStartCommand } from '../lib/node-start.js';\nimport { runNodeReadyCommand, runNodeStatusCommand } from '../lib/node-status.js';\nimport { runNodeStopCommand } from '../lib/node-stop.js';\nimport { runNodeUpgradeCommand } from '../lib/node-upgrade.js';\n\nexport function createNodeCommand(config: CliConfig): Command {\n const node = new Command('node').description('Node management');\n\n node\n .command('start')\n .option('--daemon', 'Start node in detached background mode (node + runtime)')\n .option('--runtime-proxy-listen <host:port>', 'Runtime monitor proxy listen address')\n .option('--event-stream <format>', 'Event stream format for --json mode (jsonl)', 'jsonl')\n .option('--quiet-fnn', 'Do not mirror fnn stdout/stderr to console; keep file persistence')\n .option('--json')\n .action(async (options) => {\n await runNodeStartCommand(config, options);\n });\n\n node\n .command('stop')\n .option('--json')\n .action(async (options) => {\n await runNodeStopCommand(config, options);\n });\n\n node\n .command('status')\n .option('--json')\n .action(async (options) => {\n await runNodeStatusCommand(config, options);\n });\n\n node\n .command('ready')\n .description('Agent-oriented readiness summary for automation')\n .option('--json')\n .action(async (options) => {\n await runNodeReadyCommand(config, options);\n });\n\n node\n .command('upgrade')\n .description('Upgrade the Fiber node binary and migrate the database if needed')\n .option('--version <version>', 'Target Fiber version (default: latest)')\n .option('--no-backup', 'Skip creating a store backup before migration')\n .option('--check-only', 'Only check if migration is needed, do not migrate')\n .option(\n '--force-migrate',\n 'Force migration attempt even when compatibility check reports incompatible data',\n )\n .option('--json')\n .action(async (options) => {\n await runNodeUpgradeCommand(config, options);\n });\n\n return node;\n}\n","import { spawn } from 'node:child_process';\nimport { mkdirSync } from 'node:fs';\nimport { join } from 'node:path';\nimport {\n createKeyManager,\n ensureFiberBinary,\n type FiberNodeConfig,\n ProcessManager,\n} from '@fiber-pay/node';\nimport { startRuntimeService } from '@fiber-pay/runtime';\nimport { getBinaryManagerInstallDirOrThrow, resolveBinaryPath } from './binary-path.js';\nimport { autoConnectBootnodes, extractBootnodeAddrs } from './bootnode.js';\nimport { type CliConfig, ensureNodeConfigFile } from './config.js';\nimport { printJsonError, printJsonEvent } from './format.js';\nimport { appendToTodayLog, resolveLogDirForDate } from './log-files.js';\nimport { runMigrationGuard } from './node-migration.js';\nimport {\n getBinaryVersion,\n startRuntimeDaemonFromNode,\n stopRuntimeDaemonFromNode,\n} from './node-runtime-daemon.js';\nimport { isProcessRunning, readPidFile, removePidFile, writePidFile } from './pid.js';\nimport { createRpcClient } from './rpc.js';\nimport { removeRuntimeFiles, writeRuntimeMeta, writeRuntimePid } from './runtime-meta.js';\nimport {\n findListeningProcessByPort,\n isFiberRuntimeCommand,\n terminateProcess,\n} from './runtime-port.js';\n\nexport interface NodeStartOptions {\n daemon?: boolean;\n runtimeProxyListen?: string;\n eventStream?: string;\n quietFnn?: boolean;\n json?: boolean;\n}\n\nexport async function runNodeStartCommand(\n config: CliConfig,\n options: NodeStartOptions,\n): Promise<void> {\n const json = Boolean(options.json);\n const daemon = Boolean(options.daemon);\n const isNodeChild = process.env.FIBER_NODE_CHILD === '1';\n const quietFnn = Boolean(options.quietFnn);\n const eventStream = String(options.eventStream ?? 'jsonl').toLowerCase();\n const emitStage = (stage: string, status: 'ok' | 'error', data: Record<string, unknown>) => {\n if (!json) return;\n printJsonEvent('startup_stage', { stage, status, ...data });\n };\n const emitFnnLog = (stream: 'stdout' | 'stderr', text: string) => {\n if (quietFnn) {\n return;\n }\n\n if (json) {\n printJsonEvent('fnn_log', { stream, text });\n return;\n }\n\n const target = stream === 'stderr' ? process.stderr : process.stdout;\n const payload = text.endsWith('\\n') ? text : `${text}\\n`;\n target.write(`[fnn:${stream}] ${payload}`);\n };\n if (json && eventStream !== 'jsonl') {\n printJsonError({\n code: 'NODE_EVENT_STREAM_INVALID',\n message: `Unsupported --event-stream format: ${options.eventStream}. Expected: jsonl`,\n recoverable: true,\n suggestion: 'Use `--event-stream jsonl` when using --json.',\n details: { provided: options.eventStream, expected: ['jsonl'] },\n });\n process.exit(1);\n }\n\n if (daemon && !isNodeChild) {\n const cliEntrypoint = process.argv[1];\n if (!cliEntrypoint) {\n const message = 'Unable to resolve CLI entrypoint path for --daemon mode';\n if (json) {\n printJsonError({\n code: 'NODE_DAEMON_START_FAILED',\n message,\n recoverable: true,\n suggestion: 'Retry without --daemon or check CLI invocation method.',\n });\n } else {\n console.error(`❌ ${message}`);\n }\n process.exit(1);\n }\n\n const childArgs = process.argv.slice(2).filter((arg) => arg !== '--daemon');\n const child = spawn(process.execPath, [cliEntrypoint, ...childArgs], {\n detached: true,\n stdio: 'ignore',\n cwd: process.cwd(),\n env: {\n ...process.env,\n FIBER_NODE_CHILD: '1',\n FIBER_NODE_RUNTIME_DAEMON: '1',\n },\n });\n child.unref();\n\n const childPid = child.pid;\n if (!childPid) {\n const message = 'Failed to spawn node daemon process';\n if (json) {\n printJsonError({\n code: 'NODE_DAEMON_START_FAILED',\n message,\n recoverable: true,\n suggestion: 'Retry node start and inspect system process limits.',\n });\n } else {\n console.error(`❌ ${message}`);\n }\n process.exit(1);\n }\n\n if (json) {\n printJsonEvent('node_daemon_starting', {\n pid: childPid,\n runtimeDaemon: true,\n });\n } else {\n console.log(`Node daemon starting (PID: ${childPid})`);\n console.log('Use `fiber-pay node status --json` to verify readiness.');\n }\n return;\n }\n\n emitStage('init', 'ok', { rpcUrl: config.rpcUrl, dataDir: config.dataDir });\n const existingPid = readPidFile(config.dataDir);\n if (existingPid && isProcessRunning(existingPid)) {\n if (json) {\n printJsonError({\n code: 'NODE_ALREADY_RUNNING',\n message: `Node is already running (PID: ${existingPid})`,\n recoverable: true,\n suggestion: 'Skip start or run `fiber-pay node stop` before retrying.',\n details: { pid: existingPid },\n });\n } else {\n console.log(`❌ Node is already running (PID: ${existingPid})`);\n }\n process.exit(1);\n }\n\n const runtimeDaemon = process.env.FIBER_NODE_RUNTIME_DAEMON === '1';\n const runtimeProxyListen = String(\n options.runtimeProxyListen ?? config.runtimeProxyListen ?? '127.0.0.1:8229',\n );\n const proxyListenSource: 'cli' | 'profile' | 'default' = options.runtimeProxyListen\n ? 'cli'\n : config.runtimeProxyListen\n ? 'profile'\n : 'default';\n const runtimeStateFilePath = join(config.dataDir, 'runtime-state.json');\n const logsBaseDir = join(config.dataDir, 'logs');\n mkdirSync(logsBaseDir, { recursive: true });\n // Ensure today's date directory exists at startup\n resolveLogDirForDate(config.dataDir);\n\n const resolvedBinary = resolveBinaryPath(config);\n const binaryPath = resolvedBinary.binaryPath;\n if (resolvedBinary.source === 'profile-managed') {\n const installDir = getBinaryManagerInstallDirOrThrow(resolvedBinary);\n await ensureFiberBinary({ installDir });\n }\n const binaryVersion = getBinaryVersion(binaryPath);\n const configFilePath = ensureNodeConfigFile(config.dataDir, config.network);\n emitStage('binary_resolved', 'ok', {\n binaryPath,\n binaryVersion,\n binarySource: resolvedBinary.source,\n configFilePath,\n });\n\n if (!json) {\n console.log(`🧩 Binary: ${binaryPath}`);\n console.log(`🧩 Version: ${binaryVersion}`);\n }\n\n // Check if database migration is needed before starting the node\n const guardResult = await runMigrationGuard({ dataDir: config.dataDir, binaryPath, json });\n if (guardResult.checked) {\n emitStage('migration_check', 'ok', {\n storePath: `${config.dataDir}/store`,\n needed: false,\n });\n } else {\n emitStage('migration_check', 'ok', {\n storePath: `${config.dataDir}/store`,\n skipped: true,\n reason: guardResult.skippedReason,\n });\n }\n\n const nodeConfig: FiberNodeConfig = {\n binaryPath,\n dataDir: config.dataDir,\n configFilePath,\n chain: config.network,\n keyPassword: config.keyPassword,\n };\n\n try {\n const keyManager = createKeyManager(config.dataDir, {\n encryptionPassword: config.keyPassword,\n autoGenerate: true,\n });\n await keyManager.initialize();\n emitStage('key_initialized', 'ok', {});\n } catch (error) {\n const message = `Failed to initialize node keys: ${error instanceof Error ? error.message : String(error)}`;\n emitStage('key_initialized', 'error', { code: 'NODE_KEY_INIT_FAILED', message });\n if (json) {\n printJsonError({\n code: 'NODE_KEY_INIT_FAILED',\n message,\n recoverable: true,\n suggestion: 'Verify key password and write permission for the data directory.',\n details: { dataDir: config.dataDir },\n });\n } else {\n console.error(`❌ ${message}`);\n }\n process.exit(1);\n }\n\n const processManager = new ProcessManager(nodeConfig);\n let earlyStop: { code: number | null; signal: NodeJS.Signals | null } | null = null;\n const formatStopDetails = (\n stop: { code: number | null; signal: NodeJS.Signals | null } | null,\n ): string => {\n if (!stop) return '';\n return ` (code: ${stop.code ?? 'null'}, signal: ${stop.signal ?? 'null'})`;\n };\n processManager.on('stopped', (code, signal) => {\n earlyStop = { code, signal };\n removePidFile(config.dataDir);\n });\n processManager.on('stdout', (text) => {\n appendToTodayLog(config.dataDir, 'fnn.stdout.log', text);\n emitFnnLog('stdout', text);\n });\n processManager.on('stderr', (text) => {\n appendToTodayLog(config.dataDir, 'fnn.stderr.log', text);\n emitFnnLog('stderr', text);\n });\n await processManager.start();\n const processManagerState = processManager as unknown as {\n process?: { pid?: number };\n };\n const processId = processManagerState.process?.pid;\n if (processId !== undefined) {\n writePidFile(config.dataDir, processId);\n }\n emitStage('process_started', 'ok', { pid: processId ?? null });\n\n let runtime: Awaited<ReturnType<typeof startRuntimeService>> | undefined;\n\n const rpc = createRpcClient(config);\n let rpcReady = true;\n try {\n await rpc.waitForReady({ timeout: 30000, interval: 500 });\n } catch {\n rpcReady = false;\n }\n\n if (earlyStop || processManager.getState() === 'stopped') {\n const details = formatStopDetails(earlyStop);\n emitStage('process_started', 'error', {\n code: 'NODE_STARTUP_EXITED',\n details,\n });\n if (json) {\n printJsonError({\n code: 'NODE_STARTUP_EXITED',\n message: `Fiber node exited during startup${details}`,\n recoverable: true,\n suggestion: 'Inspect fnn logs and verify config ports are free before retrying.',\n details: earlyStop ?? undefined,\n });\n } else {\n console.error(`❌ Fiber node exited during startup${details}`);\n }\n removePidFile(config.dataDir);\n if (runtimeDaemon) {\n stopRuntimeDaemonFromNode({ dataDir: config.dataDir, rpcUrl: config.rpcUrl });\n } else if (runtime) {\n await runtime.stop().catch(() => undefined);\n }\n removeRuntimeFiles(config.dataDir);\n process.exit(1);\n }\n\n try {\n const runtimePortProcess = findListeningProcessByPort(runtimeProxyListen);\n if (runtimePortProcess) {\n if (isFiberRuntimeCommand(runtimePortProcess.command)) {\n const terminated = await terminateProcess(runtimePortProcess.pid);\n if (!terminated) {\n throw new Error(\n `Runtime proxy ${runtimeProxyListen} is occupied by stale fiber-pay runtime PID ${runtimePortProcess.pid}, but termination failed`,\n );\n }\n removeRuntimeFiles(config.dataDir);\n emitStage('runtime_preflight', 'ok', {\n proxyListen: runtimeProxyListen,\n cleanedStaleProcessPid: runtimePortProcess.pid,\n });\n } else if (runtimePortProcess.command) {\n const details = runtimePortProcess.command\n ? `PID ${runtimePortProcess.pid} (${runtimePortProcess.command})`\n : `PID ${runtimePortProcess.pid}`;\n throw new Error(\n `Runtime proxy ${runtimeProxyListen} is already in use by non-fiber-pay process: ${details}`,\n );\n } else {\n throw new Error(\n `Runtime proxy ${runtimeProxyListen} is already in use by process PID ${runtimePortProcess.pid}. ` +\n 'Unable to determine command owner; inspect this PID manually before retrying.',\n );\n }\n }\n\n if (runtimeDaemon) {\n const daemonStart = startRuntimeDaemonFromNode({\n dataDir: config.dataDir,\n rpcUrl: config.rpcUrl,\n proxyListen: runtimeProxyListen,\n stateFilePath: runtimeStateFilePath,\n alertLogsBaseDir: logsBaseDir,\n });\n if (!daemonStart.ok) {\n throw new Error(daemonStart.message);\n }\n } else {\n runtime = await startRuntimeService({\n fiberRpcUrl: config.rpcUrl,\n proxy: {\n enabled: true,\n listen: runtimeProxyListen,\n },\n storage: {\n stateFilePath: runtimeStateFilePath,\n },\n alerts: [{ type: 'stdout' }, { type: 'daily-file', baseLogsDir: logsBaseDir }],\n jobs: {\n enabled: true,\n dbPath: join(config.dataDir, 'runtime-jobs.db'),\n },\n });\n\n const runtimeStatus = runtime.service.getStatus();\n writeRuntimePid(config.dataDir, process.pid);\n const todayLogDir = resolveLogDirForDate(config.dataDir);\n writeRuntimeMeta(config.dataDir, {\n pid: process.pid,\n startedAt: runtimeStatus.startedAt,\n fiberRpcUrl: runtimeStatus.targetUrl,\n proxyListen: runtimeStatus.proxyListen,\n stateFilePath: runtimeStateFilePath,\n alertLogFilePath: join(todayLogDir, 'runtime.alerts.jsonl'),\n fnnStdoutLogPath: join(todayLogDir, 'fnn.stdout.log'),\n fnnStderrLogPath: join(todayLogDir, 'fnn.stderr.log'),\n logsBaseDir,\n daemon: false,\n });\n }\n\n emitStage('runtime_started', 'ok', {\n proxyListen: runtimeProxyListen,\n daemon: runtimeDaemon,\n });\n } catch (error) {\n const message = `Runtime failed to start: ${error instanceof Error ? error.message : String(error)}`;\n emitStage('runtime_started', 'error', {\n code: 'NODE_RUNTIME_START_FAILED',\n message,\n proxyListen: runtimeProxyListen,\n });\n if (json) {\n printJsonError({\n code: 'NODE_RUNTIME_START_FAILED',\n message,\n recoverable: true,\n suggestion: 'Retry with a free --runtime-proxy-listen port.',\n details: {\n runtimeProxyListen,\n },\n });\n } else {\n console.error(`❌ ${message}`);\n }\n\n removeRuntimeFiles(config.dataDir);\n removePidFile(config.dataDir);\n await processManager.stop().catch(() => undefined);\n process.exit(1);\n }\n\n if (!rpcReady) {\n emitStage('rpc_ready', 'error', {\n code: 'NODE_RPC_NOT_READY',\n timeoutSeconds: 30,\n });\n if (json) {\n printJsonError({\n code: 'NODE_RPC_NOT_READY',\n message: 'RPC did not become ready within 30s. Node startup failed.',\n recoverable: true,\n suggestion: 'Retry after a delay and verify RPC port + config consistency.',\n details: { timeoutSeconds: 30, rpcUrl: config.rpcUrl },\n });\n } else {\n console.error('❌ RPC did not become ready within 30s. Node startup failed.');\n }\n const stderrTail = processManager.getStderr(12).join('').trim();\n const stdoutTail = processManager.getStdout(12).join('').trim();\n if (!json && stderrTail.length > 0) {\n console.error('--- fnn stderr (tail) ---');\n console.error(stderrTail);\n }\n if (!json && stdoutTail.length > 0) {\n console.error('--- fnn stdout (tail) ---');\n console.error(stdoutTail);\n }\n\n removePidFile(config.dataDir);\n if (runtimeDaemon) {\n stopRuntimeDaemonFromNode({ dataDir: config.dataDir, rpcUrl: config.rpcUrl });\n } else if (runtime) {\n await runtime.stop().catch(() => undefined);\n removeRuntimeFiles(config.dataDir);\n }\n await processManager.stop().catch(() => undefined);\n process.exit(1);\n }\n emitStage('rpc_ready', 'ok', { rpcUrl: config.rpcUrl });\n\n const bootnodes = nodeConfig.configFilePath\n ? extractBootnodeAddrs(nodeConfig.configFilePath)\n : extractBootnodeAddrs(join(config.dataDir, 'config.yml'));\n if (bootnodes.length > 0) {\n await autoConnectBootnodes(rpc, bootnodes);\n }\n emitStage('bootnodes_connected', 'ok', { count: bootnodes.length });\n\n if (earlyStop || processManager.getState() === 'stopped') {\n const details = formatStopDetails(earlyStop);\n emitStage('bootnodes_connected', 'error', {\n code: 'NODE_STARTUP_EXITED',\n details,\n });\n if (json) {\n printJsonError({\n code: 'NODE_STARTUP_EXITED',\n message: `Fiber node exited during startup${details}`,\n recoverable: true,\n suggestion: 'Inspect fnn logs and verify config ports are free before retrying.',\n details: earlyStop ?? undefined,\n });\n } else {\n console.error(`❌ Fiber node exited during startup${details}`);\n }\n removePidFile(config.dataDir);\n process.exit(1);\n }\n\n if (json) {\n emitStage('startup_complete', 'ok', {\n pid: processId ?? null,\n rpcUrl: config.rpcUrl,\n });\n printJsonEvent('node_started', {\n rpcUrl: config.rpcUrl,\n binaryPath,\n binaryVersion,\n pid: processId ?? null,\n runtimeEnabled: true,\n runtimeDaemon,\n quietFnn,\n proxyUrl: `http://${runtimeProxyListen}`,\n proxyListenSource,\n logs: {\n baseDir: logsBaseDir,\n todayDir: resolveLogDirForDate(config.dataDir),\n },\n });\n } else {\n console.log('✅ Fiber node started successfully!');\n console.log(` RPC endpoint: ${config.rpcUrl}`);\n console.log(\n ` Runtime proxy: http://${runtimeProxyListen} (browser-safe endpoint + monitoring)`,\n );\n console.log(` Runtime mode: ${runtimeDaemon ? 'daemon' : 'embedded'}`);\n console.log(` Log files: ${logsBaseDir}`);\n console.log(' Press Ctrl+C to stop.');\n }\n\n let shutdownRequested = false;\n const shutdown = async () => {\n if (shutdownRequested) return;\n shutdownRequested = true;\n if (!json) {\n console.log('\\n🛑 Shutting down...');\n }\n if (runtimeDaemon) {\n stopRuntimeDaemonFromNode({ dataDir: config.dataDir, rpcUrl: config.rpcUrl });\n } else if (runtime) {\n await runtime.stop();\n }\n removeRuntimeFiles(config.dataDir);\n removePidFile(config.dataDir);\n await processManager.stop();\n if (json) {\n printJsonEvent('node_stopped', { reason: 'signal' });\n } else {\n console.log('✅ Node stopped.');\n }\n };\n\n await new Promise<void>((resolve) => {\n const keepAlive = setInterval(() => undefined, 60_000);\n\n const cleanup = () => {\n clearInterval(keepAlive);\n process.off('SIGINT', onSigInt);\n process.off('SIGTERM', onSigTerm);\n processManager.off('stopped', onStopped);\n resolve();\n };\n\n const onStopped = () => {\n cleanup();\n };\n\n const onSigInt = () => {\n shutdown().finally(cleanup);\n };\n\n const onSigTerm = () => {\n shutdown().finally(cleanup);\n };\n\n process.on('SIGINT', onSigInt);\n process.on('SIGTERM', onSigTerm);\n processManager.on('stopped', onStopped);\n });\n\n if (!shutdownRequested) {\n if (json) {\n printJsonError({\n code: 'NODE_STOPPED_UNEXPECTEDLY',\n message: 'Fiber node stopped unexpectedly.',\n recoverable: true,\n suggestion: 'Check process logs and restart the node when configuration is healthy.',\n });\n } else {\n console.error('❌ Fiber node stopped unexpectedly.');\n }\n removePidFile(config.dataDir);\n if (runtimeDaemon) {\n stopRuntimeDaemonFromNode({ dataDir: config.dataDir, rpcUrl: config.rpcUrl });\n }\n removeRuntimeFiles(config.dataDir);\n process.exit(1);\n }\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport type { FiberRpcClient } from '@fiber-pay/sdk';\nimport { parse as parseYaml } from 'yaml';\n\nexport function extractBootnodeAddrs(configFilePath: string): string[] {\n if (!existsSync(configFilePath)) return [];\n\n try {\n const content = readFileSync(configFilePath, 'utf-8');\n const doc = parseYaml(content);\n const addrs = doc?.fiber?.bootnode_addrs;\n if (!Array.isArray(addrs)) return [];\n return addrs.filter((a): a is string => typeof a === 'string' && a.startsWith('/ip'));\n } catch {\n return [];\n }\n}\n\nexport async function autoConnectBootnodes(\n rpc: FiberRpcClient,\n bootnodes: string[],\n): Promise<void> {\n if (bootnodes.length === 0) return;\n\n console.log(`🔗 Connecting to ${bootnodes.length} bootnode(s)...`);\n for (const addr of bootnodes) {\n const shortId = addr.match(/\\/p2p\\/(.+)$/)?.[1]?.slice(0, 12) || addr.slice(-12);\n try {\n await rpc.connectPeer({ address: addr });\n console.log(` ✅ Connected to ${shortId}...`);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n if (msg.toLowerCase().includes('already')) {\n console.log(` ✅ Already connected to ${shortId}...`);\n } else {\n console.error(` ⚠️ Failed to connect to ${shortId}...: ${msg}`);\n }\n }\n }\n}\n","/**\n * Shared migration-guard logic used by both `node start` and `node upgrade`.\n */\n\nimport { dirname } from 'node:path';\nimport { BinaryManager, type MigrationCheckResult, MigrationManager } from '@fiber-pay/node';\nimport { printJsonError } from './format.js';\nimport { replaceRawMigrateHint } from './migration-utils.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface MigrationGuardResult {\n /** Whether the guard ran (false when no store exists or fnn-migrate is missing) */\n checked: boolean;\n /** The migration check result (undefined when `checked` is false) */\n migrationCheck?: MigrationCheckResult;\n /** When the guard was skipped, explain why */\n skippedReason?: string;\n}\n\nexport interface MigrationGuardOptions {\n /** Absolute data directory */\n dataDir: string;\n /**\n * Resolved binary path of `fnn`.\n * The migrate binary is looked up relative to the *directory* of this path,\n * so it works even when binaryPath is overridden via config.\n */\n binaryPath: string;\n /** Output machine-readable JSON instead of human-friendly text */\n json: boolean;\n}\n\n// =============================================================================\n// Pre-start migration guard\n// =============================================================================\n\n/**\n * Check whether the on-disk store requires migration before starting fnn.\n *\n * - If migration is needed the function prints an error and calls\n * `process.exit(1)`.\n * - If `fnn-migrate` is unavailable the check is silently skipped (the node\n * itself will fail later with a clear error if the schema really is stale).\n * - Returns a result describing what happened so callers can emit structured\n * events (e.g. startup stages).\n */\nexport async function runMigrationGuard(\n opts: MigrationGuardOptions,\n): Promise<MigrationGuardResult> {\n const { dataDir, binaryPath, json } = opts;\n\n if (!MigrationManager.storeExists(dataDir)) {\n return { checked: false, skippedReason: 'store does not exist' };\n }\n\n const storePath = MigrationManager.resolveStorePath(dataDir);\n const binaryDir = dirname(binaryPath);\n const bm = new BinaryManager(binaryDir);\n const migrateBinPath = bm.getMigrateBinaryPath();\n\n let migrationCheck: MigrationCheckResult;\n try {\n const migrationManager = new MigrationManager(migrateBinPath);\n migrationCheck = await migrationManager.check(storePath);\n } catch {\n // fnn-migrate binary may not exist (e.g. older install). Skip silently.\n return { checked: false, skippedReason: 'fnn-migrate binary not available' };\n }\n\n if (migrationCheck.needed) {\n const message = migrationCheck.valid\n ? 'Database migration required. Run `fiber-pay node upgrade --force-migrate` before starting.'\n : replaceRawMigrateHint(migrationCheck.message);\n\n if (json) {\n printJsonError({\n code: 'MIGRATION_REQUIRED',\n message,\n recoverable: true,\n suggestion: `Back up your store first (directory: \"${storePath}\"). Then run \\`fiber-pay node upgrade --force-migrate\\`. If migration still fails, close channels on the old fnn version, remove the store, and restart with a fresh store. If backup exists, restore it to roll back.`,\n details: {\n storePath,\n migrationCheck: {\n ...migrationCheck,\n message,\n },\n },\n });\n } else {\n console.error(`❌ ${message}`);\n console.error(` 1) Back up store directory: ${storePath}`);\n console.error(' 2) Run: fiber-pay node upgrade --force-migrate');\n console.error(\n ' 3) If it still fails, close channels on old fnn, remove store, then restart.',\n );\n console.error(' 4) If backup exists, restore it to roll back.');\n }\n process.exit(1);\n }\n\n return { checked: true, migrationCheck };\n}\n","export function replaceRawMigrateHint(message: string): string {\n return message.replace(\n /Fiber need to run some database migrations, please run `fnn-migrate[^`]*` to start migrations\\.?/g,\n 'Fiber database migration is required.',\n );\n}\n\nexport function normalizeMigrationCheck<T extends { message: string }>(check: T): T {\n return {\n ...check,\n message: replaceRawMigrateHint(check.message),\n };\n}\n","import { spawnSync } from 'node:child_process';\nimport { isProcessRunning } from './pid.js';\n\nexport interface PortProcessInfo {\n pid: number;\n command?: string;\n}\n\nexport function parsePortFromListen(listen: string): number | undefined {\n const value = listen.trim();\n if (!value) {\n return undefined;\n }\n\n const lastColon = value.lastIndexOf(':');\n if (lastColon < 0 || lastColon === value.length - 1) {\n return undefined;\n }\n\n const port = Number(value.slice(lastColon + 1));\n if (!Number.isInteger(port) || port < 1 || port > 65535) {\n return undefined;\n }\n return port;\n}\n\nexport function extractFirstPidFromLsofOutput(output: string): number | undefined {\n for (const line of output.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed.startsWith('p') || trimmed.length < 2) {\n continue;\n }\n const pid = Number(trimmed.slice(1));\n if (Number.isInteger(pid) && pid > 0) {\n return pid;\n }\n }\n return undefined;\n}\n\nexport function readProcessCommand(pid: number): string | undefined {\n const result = spawnSync('ps', ['-p', String(pid), '-o', 'command='], {\n encoding: 'utf-8',\n });\n if (result.error || result.status !== 0) {\n return undefined;\n }\n const command = (result.stdout ?? '').trim();\n return command.length > 0 ? command : undefined;\n}\n\nexport function findListeningProcessByPort(listen: string): PortProcessInfo | undefined {\n const port = parsePortFromListen(listen);\n if (!port) {\n return undefined;\n }\n\n const result = spawnSync('lsof', ['-nP', `-iTCP:${port}`, '-sTCP:LISTEN', '-Fp'], {\n encoding: 'utf-8',\n });\n if (result.error || result.status !== 0) {\n return undefined;\n }\n\n const pid = extractFirstPidFromLsofOutput(result.stdout ?? '');\n if (!pid) {\n return undefined;\n }\n\n return {\n pid,\n command: readProcessCommand(pid),\n };\n}\n\nexport function isFiberRuntimeCommand(command: string | undefined): boolean {\n if (!command) {\n return false;\n }\n\n const normalized = command.toLowerCase();\n const hasFiberIdentifier =\n normalized.includes('fiber-pay') ||\n normalized.includes('@fiber-pay/cli') ||\n normalized.includes('/packages/cli/dist/cli.js') ||\n normalized.includes('\\\\packages\\\\cli\\\\dist\\\\cli.js') ||\n normalized.includes('/dist/cli.js') ||\n normalized.includes('\\\\dist\\\\cli.js');\n\n if (!hasFiberIdentifier) {\n return false;\n }\n\n return normalized.includes('runtime') && normalized.includes('start');\n}\n\nexport async function terminateProcess(pid: number, timeoutMs = 5_000): Promise<boolean> {\n if (!isProcessRunning(pid)) {\n return true;\n }\n\n try {\n process.kill(pid, 'SIGTERM');\n } catch (error) {\n if ((error as { code?: string }).code === 'ESRCH') {\n return true;\n }\n return false;\n }\n\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n if (!isProcessRunning(pid)) {\n return true;\n }\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n\n if (!isProcessRunning(pid)) {\n return true;\n }\n\n try {\n process.kill(pid, 'SIGKILL');\n } catch (error) {\n if ((error as { code?: string }).code === 'ESRCH') {\n return true;\n }\n return false;\n }\n\n const killDeadline = Date.now() + 1_000;\n while (Date.now() < killDeadline) {\n if (!isProcessRunning(pid)) {\n return true;\n }\n await new Promise((resolve) => setTimeout(resolve, 50));\n }\n\n return !isProcessRunning(pid);\n}\n","import { existsSync } from 'node:fs';\nimport {\n buildMultiaddrFromNodeId,\n buildMultiaddrFromRpcUrl,\n ChannelState,\n nodeIdToPeerId,\n type Script,\n scriptToAddress,\n} from '@fiber-pay/sdk';\nimport { getBinaryDetails } from './binary-path.js';\nimport type { CliConfig } from './config.js';\nimport { printJsonSuccess } from './format.js';\nimport {\n buildReadyRecommendation,\n buildStalePidRecommendation,\n buildStatusRecommendation,\n summarizeChannelLiquidity,\n} from './node-recommendation.js';\nimport { getLockBalanceShannons } from './node-rpc.js';\nimport { isProcessRunning, readPidFile, removePidFile } from './pid.js';\nimport { createReadyRpcClient, resolveRpcEndpoint } from './rpc.js';\n\nexport interface NodeStatusOptions {\n json?: boolean;\n}\n\nexport async function runNodeStatusCommand(\n config: CliConfig,\n options: NodeStatusOptions,\n): Promise<void> {\n const json = Boolean(options.json);\n const pid = readPidFile(config.dataDir);\n const resolvedRpc = resolveRpcEndpoint(config);\n const { resolvedBinary, info: binaryInfo } = await getBinaryDetails(config);\n const configExists = existsSync(config.configPath);\n const nodeRunning = Boolean(pid && isProcessRunning(pid));\n\n let rpcResponsive = false;\n let nodeId: string | null = null;\n let addresses: string[] = [];\n let chainHash: string | null = null;\n let version: string | null = null;\n let peerId: string | null = null;\n let peersCount = 0;\n let peerIdError: string | null = null;\n let multiaddr: string | null = null;\n let multiaddrError: string | null = null;\n let multiaddrInferred = false;\n let channelsTotal = 0;\n let channelsReady = 0;\n let pendingChannelCount = 0;\n let canSend = false;\n let canReceive = false;\n let localCkb = 0;\n let remoteCkb = 0;\n let fundingAddress: string | null = null;\n let fundingLockScript: Script | null = null;\n let fundingCkb = 0;\n let fundingBalanceError: string | null = null;\n\n if (nodeRunning) {\n try {\n const rpc = await createReadyRpcClient(config);\n const nodeInfo = await rpc.nodeInfo();\n const channels = await rpc.listChannels({ include_closed: false });\n rpcResponsive = true;\n\n nodeId = nodeInfo.node_id;\n addresses = nodeInfo.addresses;\n chainHash = nodeInfo.chain_hash;\n version = nodeInfo.version;\n peersCount = parseInt(nodeInfo.peers_count, 16);\n try {\n peerId = await nodeIdToPeerId(nodeInfo.node_id);\n } catch (error) {\n peerIdError = error instanceof Error ? error.message : String(error);\n }\n\n const baseAddress = nodeInfo.addresses[0];\n if (baseAddress) {\n try {\n multiaddr = await buildMultiaddrFromNodeId(baseAddress, nodeInfo.node_id);\n } catch (error) {\n multiaddrError = error instanceof Error ? error.message : String(error);\n }\n } else if (peerId) {\n try {\n multiaddr = buildMultiaddrFromRpcUrl(config.rpcUrl, peerId);\n multiaddrInferred = true;\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n multiaddrError = `no advertised addresses; infer failed: ${reason}`;\n }\n }\n\n channelsTotal = channels.channels.length;\n const readyChannels = channels.channels.filter(\n (channel) => channel.state?.state_name === ChannelState.ChannelReady,\n );\n channelsReady = readyChannels.length;\n pendingChannelCount = Math.max(channelsTotal - channelsReady, 0);\n const liquidity = summarizeChannelLiquidity(readyChannels);\n canSend = liquidity.canSend;\n canReceive = liquidity.canReceive;\n localCkb = liquidity.localCkb;\n remoteCkb = liquidity.remoteCkb;\n\n fundingAddress = scriptToAddress(nodeInfo.default_funding_lock_script, config.network);\n fundingLockScript = nodeInfo.default_funding_lock_script as Script;\n if (config.ckbRpcUrl) {\n try {\n const fundingBalance = await getLockBalanceShannons(config.ckbRpcUrl, fundingLockScript);\n fundingCkb = Number(fundingBalance) / 1e8;\n } catch (error) {\n fundingBalanceError =\n error instanceof Error\n ? error.message\n : 'Failed to query CKB balance for funding address';\n }\n } else {\n fundingBalanceError =\n 'CKB RPC URL not configured (set ckb.rpc_url in config.yml or FIBER_CKB_RPC_URL)';\n }\n } catch {\n rpcResponsive = false;\n }\n } else if (pid) {\n removePidFile(config.dataDir);\n }\n\n const { recommendation, reasons } = buildStatusRecommendation({\n binaryReady: binaryInfo.ready,\n configExists,\n nodeRunning,\n rpcResponsive,\n channelsReady,\n canSend,\n canReceive,\n });\n\n const output = {\n running: nodeRunning,\n pid: pid ?? null,\n rpcResponsive,\n rpcUrl: config.rpcUrl,\n rpcTarget: resolvedRpc.target,\n resolvedRpcUrl: resolvedRpc.url,\n nodeId,\n addresses,\n chainHash,\n version,\n peerId,\n peersCount,\n peerIdError,\n multiaddr,\n multiaddrError,\n multiaddrInferred,\n fundingLockScript,\n checks: {\n binary: {\n path: binaryInfo.path,\n ready: binaryInfo.ready,\n version: binaryInfo.version,\n source: resolvedBinary.source,\n managedPath: resolvedBinary.managedPath,\n resolvedPath: resolvedBinary.binaryPath,\n },\n config: {\n path: config.configPath,\n exists: configExists,\n network: config.network,\n rpcUrl: config.rpcUrl,\n },\n node: {\n running: nodeRunning,\n pid: pid ?? null,\n rpcReachable: rpcResponsive,\n rpcTarget: resolvedRpc.target,\n rpcClientUrl: resolvedRpc.url,\n },\n channels: {\n total: channelsTotal,\n ready: channelsReady,\n pending: pendingChannelCount,\n canSend,\n canReceive,\n },\n },\n balance: {\n totalCkb: localCkb + fundingCkb,\n channelLocalCkb: localCkb,\n availableToSend: localCkb,\n availableToReceive: remoteCkb,\n channelCount: channelsTotal,\n activeChannelCount: channelsReady,\n fundingAddress,\n fundingAddressTotalCkb: fundingCkb,\n fundingBalanceError,\n },\n recommendation,\n reasons,\n };\n\n if (json) {\n printJsonSuccess(output);\n return;\n }\n\n if (output.running) {\n console.log(`✅ Node is running (PID: ${output.pid})`);\n if (output.rpcResponsive) {\n console.log(` Node ID: ${String(output.nodeId)}`);\n if (output.version) {\n console.log(` Version: ${String(output.version)}`);\n }\n if (output.chainHash) {\n console.log(` Chain Hash: ${String(output.chainHash)}`);\n }\n if (output.peerId) {\n console.log(` Peer ID: ${String(output.peerId)}`);\n } else if (output.peerIdError) {\n console.log(` Peer ID: unavailable (${String(output.peerIdError)})`);\n }\n console.log(` RPC: ${String(output.rpcUrl)}`);\n console.log(` RPC Client: ${String(output.rpcTarget)} (${String(output.resolvedRpcUrl)})`);\n if (output.multiaddr) {\n const inferredSuffix = output.multiaddrInferred\n ? ' (inferred from RPC + peerId; no advertised addresses)'\n : '';\n console.log(` Multiaddr: ${String(output.multiaddr)}${inferredSuffix}`);\n } else if (output.multiaddrError) {\n console.log(` Multiaddr: unavailable (${String(output.multiaddrError)})`);\n } else {\n console.log(' Multiaddr: unavailable');\n }\n if (output.addresses.length > 0) {\n console.log(' Addresses:');\n for (const address of output.addresses) {\n console.log(` - ${address}`);\n }\n }\n } else {\n console.log(' ⚠️ RPC not responding');\n }\n } else if (output.pid) {\n console.log(`❌ Node is not running (stale PID file: ${output.pid})`);\n } else {\n console.log('❌ Node is not running');\n }\n\n console.log('');\n console.log('Diagnostics');\n console.log(` Binary: ${output.checks.binary.ready ? 'ready' : 'missing'}`);\n console.log(` Binary Path: ${output.checks.binary.resolvedPath}`);\n console.log(` Config: ${output.checks.config.exists ? 'present' : 'missing'}`);\n console.log(` RPC: ${output.checks.node.rpcReachable ? 'reachable' : 'unreachable'}`);\n console.log(\n ` Channels: ${output.checks.channels.ready}/${output.checks.channels.pending}/${output.checks.channels.total} ready/pending/total`,\n );\n if (output.rpcResponsive) {\n console.log(` Peers: ${output.peersCount}`);\n } else {\n console.log(' Peers: unavailable');\n }\n console.log(` Can Send: ${output.checks.channels.canSend ? 'yes' : 'no'}`);\n console.log(` Can Receive: ${output.checks.channels.canReceive ? 'yes' : 'no'}`);\n console.log(` Recommendation:${output.recommendation}`);\n if (output.reasons.length > 0) {\n console.log(' Reasons:');\n for (const reason of output.reasons) {\n console.log(` - ${reason}`);\n }\n }\n\n console.log('');\n console.log('Balance');\n console.log(` Total CKB: ${output.balance.totalCkb.toFixed(8)}`);\n console.log(` Channel Local: ${output.balance.channelLocalCkb.toFixed(8)}`);\n console.log(` To Send: ${output.balance.availableToSend.toFixed(8)}`);\n console.log(` To Receive: ${output.balance.availableToReceive.toFixed(8)}`);\n console.log(\n ` Channels: ${output.balance.activeChannelCount}/${output.balance.channelCount} active/total`,\n );\n if (output.balance.fundingAddress) {\n console.log(` Funding Addr: ${output.balance.fundingAddress}`);\n }\n console.log(` Funding CKB: ${output.balance.fundingAddressTotalCkb.toFixed(8)}`);\n if (output.balance.fundingBalanceError) {\n console.log(` Funding Err: ${output.balance.fundingBalanceError}`);\n }\n}\n\nexport async function runNodeReadyCommand(\n config: CliConfig,\n options: NodeStatusOptions,\n): Promise<void> {\n const json = Boolean(options.json);\n const pid = readPidFile(config.dataDir);\n const output: Record<string, unknown> = {\n nodeRunning: false,\n rpcReachable: false,\n channelsTotal: 0,\n channelsReady: 0,\n canSend: false,\n canReceive: false,\n recommendation: 'NODE_STOPPED',\n reasons: ['Node process is not running.'],\n pid: pid ?? null,\n rpcUrl: config.rpcUrl,\n };\n\n if (pid && isProcessRunning(pid)) {\n output.nodeRunning = true;\n output.reasons = [];\n\n try {\n const rpc = await createReadyRpcClient(config);\n output.rpcReachable = true;\n const channels = await rpc.listChannels({ include_closed: false });\n output.channelsTotal = channels.channels.length;\n\n const readyChannels = channels.channels.filter(\n (channel) => channel.state?.state_name === ChannelState.ChannelReady,\n );\n output.channelsReady = readyChannels.length;\n\n const liquidity = summarizeChannelLiquidity(readyChannels);\n output.canSend = liquidity.canSend;\n output.canReceive = liquidity.canReceive;\n\n const readyRecommendation = buildReadyRecommendation({\n nodeRunning: true,\n rpcReachable: true,\n channelsReady: readyChannels.length,\n canSend: liquidity.canSend,\n canReceive: liquidity.canReceive,\n });\n output.recommendation = readyRecommendation.recommendation;\n output.reasons = readyRecommendation.reasons;\n } catch {\n output.rpcReachable = false;\n const readyRecommendation = buildReadyRecommendation({\n nodeRunning: true,\n rpcReachable: false,\n channelsReady: 0,\n canSend: false,\n canReceive: false,\n });\n output.recommendation = readyRecommendation.recommendation;\n output.reasons = readyRecommendation.reasons;\n }\n } else if (pid) {\n const staleRecommendation = buildStalePidRecommendation();\n output.recommendation = staleRecommendation.recommendation;\n output.reasons = staleRecommendation.reasons;\n removePidFile(config.dataDir);\n }\n\n if (json) {\n printJsonSuccess(output);\n } else {\n console.log('Node Readiness');\n console.log(` Node Running: ${output.nodeRunning ? 'yes' : 'no'}`);\n console.log(` RPC Reachable: ${output.rpcReachable ? 'yes' : 'no'}`);\n console.log(` Channels: ${output.channelsReady}/${output.channelsTotal} ready/total`);\n console.log(` Can Send: ${output.canSend ? 'yes' : 'no'}`);\n console.log(` Can Receive: ${output.canReceive ? 'yes' : 'no'}`);\n console.log(` Recommendation: ${String(output.recommendation)}`);\n const reasons = Array.isArray(output.reasons) ? output.reasons : [];\n if (reasons.length > 0) {\n console.log(' Reasons:');\n for (const reason of reasons) {\n console.log(` - ${String(reason)}`);\n }\n }\n }\n}\n","type StatusRecommendationInput = {\n binaryReady: boolean;\n configExists: boolean;\n nodeRunning: boolean;\n rpcResponsive: boolean;\n channelsReady: number;\n canSend: boolean;\n canReceive: boolean;\n};\n\ntype ReadyRecommendationInput = {\n nodeRunning: boolean;\n rpcReachable: boolean;\n channelsReady: number;\n canSend: boolean;\n canReceive: boolean;\n};\n\ntype RecommendationResult = {\n recommendation: string;\n reasons: string[];\n};\n\nexport function summarizeChannelLiquidity(\n readyChannels: Array<{ local_balance: string; remote_balance: string }>,\n): { canSend: boolean; canReceive: boolean; localCkb: number; remoteCkb: number } {\n const canSend = readyChannels.some((channel) => BigInt(channel.local_balance) > 0n);\n const canReceive = readyChannels.some((channel) => BigInt(channel.remote_balance) > 0n);\n\n let totalLocal = 0n;\n let totalRemote = 0n;\n for (const channel of readyChannels) {\n totalLocal += BigInt(channel.local_balance);\n totalRemote += BigInt(channel.remote_balance);\n }\n\n return {\n canSend,\n canReceive,\n localCkb: Number(totalLocal) / 1e8,\n remoteCkb: Number(totalRemote) / 1e8,\n };\n}\n\nexport function buildStatusRecommendation(input: StatusRecommendationInput): RecommendationResult {\n const reasons: string[] = [];\n\n if (!input.binaryReady) reasons.push('Fiber binary is missing or not executable.');\n if (!input.configExists) reasons.push('Config file is missing.');\n if (!input.nodeRunning) reasons.push('Node process is not running.');\n if (input.nodeRunning && !input.rpcResponsive) {\n reasons.push('Node process is running but RPC is not reachable.');\n }\n if (input.rpcResponsive && input.channelsReady === 0) {\n reasons.push('No ChannelReady channel found.');\n }\n if (input.channelsReady > 0 && !input.canSend && input.canReceive) {\n reasons.push('Send liquidity is low on ChannelReady channels.');\n }\n if (input.channelsReady > 0 && input.canSend && !input.canReceive) {\n reasons.push('Receive liquidity is low on ChannelReady channels.');\n }\n if (input.channelsReady > 0 && !input.canSend && !input.canReceive) {\n reasons.push('ChannelReady channels exist but liquidity is zero.');\n }\n\n let recommendation = 'READY';\n if (!input.binaryReady) {\n recommendation = 'INSTALL_BINARY';\n } else if (!input.configExists) {\n recommendation = 'INIT_CONFIG';\n } else if (!input.nodeRunning) {\n recommendation = 'START_NODE';\n } else if (!input.rpcResponsive) {\n recommendation = 'WAIT_RPC';\n } else if (input.channelsReady === 0) {\n recommendation = 'OPEN_CHANNEL';\n } else if (!input.canSend && !input.canReceive) {\n recommendation = 'NO_LIQUIDITY';\n } else if (!input.canSend && input.canReceive) {\n recommendation = 'SEND_CAPACITY_LOW';\n } else if (input.canSend && !input.canReceive) {\n recommendation = 'RECEIVE_CAPACITY_LOW';\n }\n\n return { recommendation, reasons };\n}\n\nexport function buildReadyRecommendation(input: ReadyRecommendationInput): RecommendationResult {\n if (!input.nodeRunning) {\n return {\n recommendation: 'NODE_STOPPED',\n reasons: ['Node process is not running.'],\n };\n }\n\n if (!input.rpcReachable) {\n return {\n recommendation: 'RPC_UNREACHABLE',\n reasons: ['Node process is running but RPC is not reachable.'],\n };\n }\n\n if (input.channelsReady === 0) {\n return {\n recommendation: 'NEED_CHANNEL',\n reasons: ['No ChannelReady channel found. Open and wait for channel readiness.'],\n };\n }\n\n if (input.canSend && input.canReceive) {\n return {\n recommendation: 'READY',\n reasons: ['Node is reachable and has send/receive liquidity.'],\n };\n }\n\n if (input.canSend) {\n return {\n recommendation: 'RECEIVE_CAPACITY_LOW',\n reasons: ['Receive liquidity is low on all ChannelReady channels.'],\n };\n }\n\n if (input.canReceive) {\n return {\n recommendation: 'SEND_CAPACITY_LOW',\n reasons: ['Send liquidity is low on all ChannelReady channels.'],\n };\n }\n\n return {\n recommendation: 'NO_LIQUIDITY',\n reasons: ['ChannelReady channels exist but both local/remote liquidity are zero.'],\n };\n}\n\nexport function buildStalePidRecommendation(): RecommendationResult {\n return {\n recommendation: 'NODE_STOPPED',\n reasons: ['Stale PID file detected and cleaned.'],\n };\n}\n","import type { Script } from '@fiber-pay/sdk';\n\nconst CELLS_PAGE_SIZE = 100;\n\ninterface IndexerCellsResponse {\n objects: Array<{ output?: { capacity?: string } }>;\n last_cursor?: string;\n}\n\nexport async function callJsonRpc<TResult>(\n url: string,\n method: string,\n params: unknown[],\n): Promise<TResult> {\n const response = await fetch(url, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status} ${response.statusText}`);\n }\n\n const payload = (await response.json()) as {\n result?: TResult;\n error?: { message?: string; code?: number };\n };\n\n if (payload.error) {\n const code = payload.error.code ?? 'unknown';\n const message = payload.error.message ?? 'JSON-RPC error';\n throw new Error(`${message} (code: ${code})`);\n }\n\n if (payload.result === undefined) {\n throw new Error('Missing JSON-RPC result');\n }\n\n return payload.result;\n}\n\nexport async function getLockBalanceShannons(\n ckbRpcUrl: string,\n lockScript: Script,\n): Promise<bigint> {\n let cursor: string | undefined;\n let total = 0n;\n const limitHex = `0x${CELLS_PAGE_SIZE.toString(16)}`;\n\n for (let i = 0; i < 2000; i++) {\n const params: unknown[] = [{ script: lockScript, script_type: 'lock' }, 'asc', limitHex];\n if (cursor) {\n params.push(cursor);\n }\n\n const page = await callJsonRpc<IndexerCellsResponse>(ckbRpcUrl, 'get_cells', params);\n const cells = page.objects ?? [];\n\n for (const cell of cells) {\n if (cell.output?.capacity) {\n total += BigInt(cell.output.capacity);\n }\n }\n\n const nextCursor = page.last_cursor;\n if (!nextCursor || nextCursor === cursor || cells.length < CELLS_PAGE_SIZE) {\n break;\n }\n cursor = nextCursor;\n }\n\n return total;\n}\n","/**\n * Implementation of `fiber-pay node stop`.\n */\n\nimport type { CliConfig } from './config.js';\nimport { printJsonError, printJsonSuccess } from './format.js';\nimport { stopRuntimeDaemonFromNode } from './node-runtime-daemon.js';\nimport { isProcessRunning, readPidFile, removePidFile } from './pid.js';\nimport { readRuntimeMeta, readRuntimePid, removeRuntimeFiles } from './runtime-meta.js';\n\nexport interface NodeStopOptions {\n json?: boolean;\n}\n\nexport async function runNodeStopCommand(\n config: CliConfig,\n options: NodeStopOptions,\n): Promise<void> {\n const json = Boolean(options.json);\n\n // Shut down the runtime daemon if running\n const runtimeMeta = readRuntimeMeta(config.dataDir);\n const runtimePid = readRuntimePid(config.dataDir);\n if (runtimeMeta?.daemon && runtimePid && isProcessRunning(runtimePid)) {\n stopRuntimeDaemonFromNode({ dataDir: config.dataDir, rpcUrl: config.rpcUrl });\n }\n removeRuntimeFiles(config.dataDir);\n\n // Check for fnn PID\n const pid = readPidFile(config.dataDir);\n if (!pid) {\n if (json) {\n printJsonError({\n code: 'NODE_NOT_RUNNING',\n message: 'No PID file found. Node may not be running.',\n recoverable: true,\n suggestion: 'Run `fiber-pay node start` first if you intend to stop a node.',\n });\n } else {\n console.log('❌ No PID file found. Node may not be running.');\n }\n process.exit(1);\n }\n\n if (!isProcessRunning(pid)) {\n if (json) {\n printJsonError({\n code: 'NODE_NOT_RUNNING',\n message: `Process ${pid} is not running. Cleaning up PID file.`,\n recoverable: true,\n suggestion: 'Start the node again if needed; stale PID has been cleaned.',\n details: { pid, stalePidFileCleaned: true },\n });\n } else {\n console.log(`❌ Process ${pid} is not running. Cleaning up PID file.`);\n }\n removePidFile(config.dataDir);\n process.exit(1);\n }\n\n if (!json) {\n console.log(`🛑 Stopping node (PID: ${pid})...`);\n }\n process.kill(pid, 'SIGTERM');\n\n // Wait up to 3 seconds for graceful shutdown\n let attempts = 0;\n while (isProcessRunning(pid) && attempts < 30) {\n await new Promise((resolve) => setTimeout(resolve, 100));\n attempts++;\n }\n\n if (isProcessRunning(pid)) {\n process.kill(pid, 'SIGKILL');\n }\n\n removePidFile(config.dataDir);\n if (json) {\n printJsonSuccess({ pid, stopped: true });\n } else {\n console.log('✅ Node stopped.');\n }\n}\n","/**\n * Implementation of `fiber-pay node upgrade`.\n */\n\nimport { BinaryManager, type DownloadProgress, MigrationManager } from '@fiber-pay/node';\nimport { getBinaryManagerInstallDirOrThrow, resolveBinaryPath } from './binary-path.js';\nimport type { CliConfig } from './config.js';\nimport { printJsonError, printJsonSuccess } from './format.js';\nimport { normalizeMigrationCheck, replaceRawMigrateHint } from './migration-utils.js';\nimport { isProcessRunning, readPidFile } from './pid.js';\n\nexport interface NodeUpgradeOptions {\n version?: string;\n backup?: boolean;\n checkOnly?: boolean;\n forceMigrate?: boolean;\n json?: boolean;\n}\n\nexport async function runNodeUpgradeCommand(\n config: CliConfig,\n options: NodeUpgradeOptions,\n): Promise<void> {\n const json = Boolean(options.json);\n const resolvedBinary = resolveBinaryPath(config);\n let installDir: string;\n try {\n installDir = getBinaryManagerInstallDirOrThrow(resolvedBinary);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (json) {\n printJsonError({\n code: 'BINARY_PATH_INCOMPATIBLE',\n message,\n recoverable: true,\n suggestion:\n 'Use `fiber-pay config profile unset binaryPath` or set binaryPath to a standard fnn filename in the target directory.',\n });\n } else {\n console.error(`❌ ${message}`);\n }\n process.exit(1);\n }\n\n const binaryManager = new BinaryManager(installDir);\n\n // Step 1: Check if node is running — must be stopped before upgrade\n const pid = readPidFile(config.dataDir);\n if (pid && isProcessRunning(pid)) {\n const msg = 'The Fiber node is currently running. Stop it before upgrading.';\n if (json) {\n printJsonError({\n code: 'NODE_RUNNING',\n message: msg,\n recoverable: true,\n suggestion: 'Run `fiber-pay node stop` first, then retry the upgrade.',\n });\n } else {\n console.error(`❌ ${msg}`);\n console.log(' Run: fiber-pay node stop');\n }\n process.exit(1);\n }\n\n // Step 2: Resolve target version\n let targetTag: string;\n if (options.version) {\n targetTag = binaryManager.normalizeTag(options.version);\n } else {\n if (!json) console.log('🔍 Resolving latest Fiber release...');\n targetTag = await binaryManager.getLatestTag();\n }\n\n if (!json) console.log(`📦 Target version: ${targetTag}`);\n\n // Step 3: Check current version\n const currentInfo = await binaryManager.getBinaryInfo();\n const targetVersion = targetTag.startsWith('v') ? targetTag.slice(1) : targetTag;\n\n // Step 4: Prepare migration-related paths\n const storePath = MigrationManager.resolveStorePath(config.dataDir);\n const migrateBinaryPath = binaryManager.getMigrateBinaryPath();\n let migrationCheck: Awaited<ReturnType<MigrationManager['check']>> | null = null;\n\n const storeExists = MigrationManager.storeExists(config.dataDir);\n\n if (!json && storeExists) {\n console.log('📂 Existing store detected.');\n }\n\n if (currentInfo.ready && currentInfo.version === targetVersion && !options.forceMigrate) {\n if (storeExists) {\n migrationCheck = await runMigrationAndReport({\n migrateBinaryPath,\n storePath,\n json,\n checkOnly: Boolean(options.checkOnly),\n targetVersion,\n backup: options.backup !== false,\n forceMigrateAttempt: false,\n });\n }\n\n const msg = migrationCheck\n ? `Already installed ${targetTag}. Store compatibility checked.`\n : `Already installed ${targetTag}. Use --force-migrate to run migration flow anyway.`;\n if (json) {\n printJsonSuccess({\n action: 'none',\n currentVersion: currentInfo.version,\n targetVersion,\n message: msg,\n migration: migrationCheck,\n });\n } else {\n console.log(`✅ ${msg}`);\n }\n return;\n }\n\n const versionMatches = currentInfo.ready && currentInfo.version === targetVersion;\n const shouldDownload = !versionMatches;\n\n if (!json && currentInfo.ready) {\n console.log(` Current version: v${currentInfo.version}`);\n }\n\n if (shouldDownload) {\n if (!json && storeExists) {\n console.log('📂 Existing store detected, will check migration after download.');\n }\n\n // Step 5: Download new binary (this also extracts fnn-migrate)\n if (!json) console.log('⬇️ Downloading new binary...');\n\n const showProgress = (progress: DownloadProgress) => {\n if (!json) {\n const percent = progress.percent !== undefined ? ` (${progress.percent}%)` : '';\n process.stdout.write(`\\r [${progress.phase}]${percent} ${progress.message}`.padEnd(80));\n if (progress.phase === 'installing') console.log();\n }\n };\n\n await binaryManager.download({\n version: targetTag,\n force: true,\n onProgress: showProgress,\n });\n } else if (!json && options.forceMigrate) {\n console.log('⏭️ Skipping binary download: target version is already installed.');\n console.log('🔁 --force-migrate enabled: attempting migration flow on existing binaries.');\n }\n\n // Step 6: Check migration if store exists\n if (storeExists) {\n migrationCheck = await runMigrationAndReport({\n migrateBinaryPath,\n storePath,\n json,\n checkOnly: Boolean(options.checkOnly),\n targetVersion,\n backup: options.backup !== false,\n forceMigrateAttempt: Boolean(options.forceMigrate),\n });\n }\n\n // Step 7: Final status\n const newInfo = await binaryManager.getBinaryInfo();\n if (json) {\n printJsonSuccess({\n action: 'upgraded',\n previousVersion: currentInfo.ready ? currentInfo.version : null,\n currentVersion: newInfo.version,\n binaryPath: newInfo.path,\n migrateBinaryPath,\n migration: migrationCheck,\n });\n } else {\n console.log('\\n✅ Upgrade complete!');\n console.log(` Version: v${newInfo.version}`);\n console.log(` Binary: ${newInfo.path}`);\n console.log('\\n Start the node with: fiber-pay node start');\n }\n}\n\n// =============================================================================\n// Internal helpers\n// =============================================================================\n\ninterface MigrationRunOptions {\n migrateBinaryPath: string;\n storePath: string;\n json: boolean;\n checkOnly: boolean;\n targetVersion: string;\n backup: boolean;\n forceMigrateAttempt: boolean;\n}\n\n/**\n * Run migration check (and optionally migrate) after a new binary has been\n * downloaded. Exits the process on unrecoverable errors.\n *\n * @returns The migration check result, or `null` if the caller should return\n * early (e.g. `--check-only`).\n */\nasync function runMigrationAndReport(\n opts: MigrationRunOptions,\n): Promise<Awaited<ReturnType<MigrationManager['check']>> | null> {\n const {\n migrateBinaryPath,\n storePath,\n json,\n checkOnly,\n targetVersion,\n backup,\n forceMigrateAttempt,\n } = opts;\n\n // Instantiate MigrationManager\n let migrationManager: MigrationManager;\n try {\n migrationManager = new MigrationManager(migrateBinaryPath);\n } catch (err) {\n const msg = err instanceof Error ? err.message : 'fnn-migrate binary not available';\n if (json) {\n printJsonError({\n code: 'MIGRATION_TOOL_MISSING',\n message: msg,\n recoverable: true,\n suggestion:\n 'Run `fiber-pay node upgrade` to reinstall binaries, then retry `fiber-pay node upgrade --force-migrate`.',\n });\n } else {\n console.error(`\\n⚠️ ${msg}`);\n console.log(\n ' Run `fiber-pay node upgrade` to reinstall binaries, then retry `fiber-pay node upgrade --force-migrate`.',\n );\n }\n process.exit(1);\n }\n\n // Run check\n if (!json) console.log('🔍 Checking store compatibility...');\n\n let migrationCheck: Awaited<ReturnType<MigrationManager['check']>>;\n try {\n migrationCheck = await migrationManager.check(storePath);\n } catch (checkErr) {\n const msg = checkErr instanceof Error ? checkErr.message : String(checkErr);\n if (json) {\n printJsonError({\n code: 'MIGRATION_TOOL_MISSING',\n message: `Migration check failed: ${msg}`,\n recoverable: true,\n suggestion:\n 'Run `fiber-pay node upgrade` to reinstall binaries, then retry `fiber-pay node upgrade --force-migrate`.',\n });\n } else {\n console.error(`\\n⚠️ Migration check failed: ${msg}`);\n console.log(\n ' Run `fiber-pay node upgrade` to reinstall binaries, then retry `fiber-pay node upgrade --force-migrate`.',\n );\n }\n process.exit(1);\n }\n\n // --check-only: report and let the caller return\n if (checkOnly) {\n const normalizedCheck = normalizeMigrationCheck(migrationCheck);\n if (json) {\n printJsonSuccess({\n action: 'check-only',\n targetVersion,\n migration: normalizedCheck,\n });\n } else {\n console.log(`\\n📋 Migration status: ${normalizedCheck.message}`);\n }\n // Signal to caller to return early\n process.exit(0);\n }\n\n if (!migrationCheck.needed) {\n if (!json) console.log(' Store is compatible, no migration needed.');\n return normalizeMigrationCheck(migrationCheck);\n }\n\n // Breaking change — cannot auto-migrate\n if (!migrationCheck.valid && !forceMigrateAttempt) {\n const normalizedMessage = replaceRawMigrateHint(migrationCheck.message);\n if (json) {\n printJsonError({\n code: 'MIGRATION_INCOMPATIBLE',\n message: normalizedMessage,\n recoverable: false,\n suggestion: `Back up your store first (directory: \"${storePath}\"). Then run \\`fiber-pay node upgrade --force-migrate\\`. If it still fails, close all channels with the old fnn version, remove the store, and restart with a fresh store. If you attempted migration with backup enabled, you can roll back by restoring the backup directory.`,\n details: {\n storePath,\n migrationCheck: {\n ...migrationCheck,\n message: normalizedMessage,\n },\n },\n });\n } else {\n console.error('\\n❌ Store migration is not possible automatically.');\n console.log(normalizedMessage);\n console.log(` 1) Back up store directory: ${storePath}`);\n console.log(' 2) Try: fiber-pay node upgrade --force-migrate');\n console.log(\n ' 3) If it still fails, close channels on old fnn, remove store, then restart.',\n );\n console.log(' 4) If migration created a backup, you can roll back by restoring it.');\n }\n process.exit(1);\n }\n\n if (!migrationCheck.valid && !json) {\n console.log('⚠️ Store check reported incompatibility, but --force-migrate is set.');\n console.log(' Attempting migration anyway with backup enabled (unless --no-backup).');\n }\n\n // Run migration\n if (!json) console.log('🔄 Running database migration...');\n\n const result = await migrationManager.migrate({\n storePath,\n backup,\n force: forceMigrateAttempt,\n });\n\n if (!result.success) {\n if (json) {\n printJsonError({\n code: 'MIGRATION_FAILED',\n message: result.message,\n recoverable: !!result.backupPath,\n suggestion: result.backupPath\n ? `To roll back, delete the current store at \"${storePath}\" and restore the backup from \"${result.backupPath}\".`\n : 'Re-download the previous version or start fresh.',\n details: { output: result.output, backupPath: result.backupPath },\n });\n } else {\n console.error('\\n❌ Migration failed.');\n console.log(result.message);\n }\n process.exit(1);\n }\n\n if (!json) {\n console.log(`✅ ${result.message}`);\n if (result.backupPath) {\n console.log(` Backup: ${result.backupPath}`);\n }\n }\n\n try {\n const postCheck = await migrationManager.check(storePath);\n return normalizeMigrationCheck(postCheck);\n } catch (err) {\n if (!json) {\n const message = err instanceof Error ? err.message : String(err);\n console.error('⚠️ Post-migration check failed; final migration status may be stale.');\n console.error(` ${message}`);\n }\n return normalizeMigrationCheck(migrationCheck);\n }\n}\n","import type { RouterHop } from '@fiber-pay/sdk';\nimport { ckbToShannons, type HexString, shannonsToCkb } from '@fiber-pay/sdk';\nimport { Command } from 'commander';\nimport { sleep } from '../lib/async.js';\nimport type { CliConfig } from '../lib/config.js';\nimport {\n formatPaymentResult,\n printJsonError,\n printJsonEvent,\n printJsonSuccess,\n printPaymentDetailHuman,\n} from '../lib/format.js';\nimport { createReadyRpcClient, resolveRpcEndpoint } from '../lib/rpc.js';\nimport {\n type RuntimeJobRecord,\n tryCreateRuntimePaymentJob,\n waitForRuntimeJobTerminal,\n} from '../lib/runtime-jobs.js';\nimport { registerPaymentRebalanceCommand } from './rebalance.js';\n\nexport function createPaymentCommand(config: CliConfig): Command {\n const payment = new Command('payment').description('Payment lifecycle and status commands');\n\n payment\n .command('send')\n .argument('[invoice]')\n .option('--invoice <invoice>')\n .option('--to <nodeId>')\n .option('--amount <ckb>')\n .option('--max-fee <ckb>')\n .option('--wait', 'Wait for runtime job terminal status when runtime proxy is active')\n .option('--timeout <seconds>', 'Wait timeout for --wait mode', '120')\n .option('--json')\n .action(async (invoiceArg, options) => {\n const rpc = await createReadyRpcClient(config);\n const json = Boolean(options.json);\n const invoice = options.invoice || invoiceArg;\n const recipientNodeId = options.to;\n const amountCkb = options.amount ? parseFloat(options.amount) : undefined;\n const maxFeeCkb = options.maxFee ? parseFloat(options.maxFee) : undefined;\n const shouldWait = Boolean(options.wait);\n const timeoutSeconds = parseInt(String(options.timeout ?? '120'), 10);\n\n if (!invoice && !recipientNodeId) {\n if (json) {\n printJsonError({\n code: 'PAYMENT_SEND_INPUT_INVALID',\n message: 'Either invoice or --to <nodeId> required',\n recoverable: true,\n suggestion: 'Provide a valid invoice, or provide both `--to` and `--amount`.',\n });\n } else {\n console.error('Error: Either invoice or --to <nodeId> required');\n }\n process.exit(1);\n }\n if (recipientNodeId && !amountCkb) {\n if (json) {\n printJsonError({\n code: 'PAYMENT_SEND_INPUT_INVALID',\n message: '--amount required when using --to',\n recoverable: true,\n suggestion: 'Add `--amount <ckb>` when using keysend mode (`--to`).',\n });\n } else {\n console.error('Error: --amount required when using --to');\n }\n process.exit(1);\n }\n\n const paymentParams = {\n invoice,\n target_pubkey: recipientNodeId as HexString | undefined,\n amount: amountCkb ? ckbToShannons(amountCkb) : undefined,\n keysend: recipientNodeId ? true : undefined,\n max_fee_amount: maxFeeCkb ? ckbToShannons(maxFeeCkb) : undefined,\n };\n\n const endpoint = resolveRpcEndpoint(config);\n\n if (endpoint.target === 'runtime-proxy') {\n const created = await tryCreateRuntimePaymentJob(endpoint.url, {\n params: {\n invoice,\n sendPaymentParams: paymentParams,\n },\n options: {\n idempotencyKey: invoice ? `payment:invoice:${invoice}` : undefined,\n },\n });\n\n if (created) {\n const job = shouldWait\n ? await waitForRuntimeJobTerminal(endpoint.url, created.id, timeoutSeconds)\n : created;\n\n const payload = {\n paymentHash: getJobPaymentHash(job) ?? 'unknown',\n status:\n job.state === 'succeeded'\n ? 'success'\n : job.state === 'failed' || job.state === 'cancelled'\n ? 'failed'\n : 'pending',\n feeCkb: getJobFeeCkb(job),\n failureReason: getJobFailure(job),\n jobId: job.id,\n jobState: job.state,\n };\n\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log('Payment job submitted');\n console.log(` Job: ${payload.jobId}`);\n console.log(` Hash: ${payload.paymentHash}`);\n console.log(` Status: ${payload.status} (${payload.jobState})`);\n console.log(` Fee: ${payload.feeCkb} CKB`);\n if (payload.failureReason) {\n console.log(` Error: ${payload.failureReason}`);\n }\n }\n return;\n }\n }\n\n // Fallback to direct RPC send_payment\n const result = await rpc.sendPayment(paymentParams);\n\n const payload = {\n paymentHash: result.payment_hash,\n status:\n result.status === 'Success'\n ? 'success'\n : result.status === 'Failed'\n ? 'failed'\n : 'pending',\n feeCkb: shannonsToCkb(result.fee),\n failureReason: result.failed_error,\n };\n\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log('Payment sent');\n console.log(` Hash: ${payload.paymentHash}`);\n console.log(` Status: ${payload.status}`);\n console.log(` Fee: ${payload.feeCkb} CKB`);\n if (payload.failureReason) {\n console.log(` Error: ${payload.failureReason}`);\n }\n }\n });\n\n registerPaymentRebalanceCommand(payment, config);\n\n payment\n .command('get')\n .argument('<paymentHash>')\n .option('--json')\n .action(async (paymentHash, options) => {\n const rpc = await createReadyRpcClient(config);\n const result = await rpc.getPayment({ payment_hash: paymentHash as HexString });\n if (options.json) {\n printJsonSuccess(formatPaymentResult(result));\n } else {\n printPaymentDetailHuman(result);\n }\n });\n\n payment\n .command('watch')\n .argument('<paymentHash>')\n .option('--interval <seconds>', 'Polling interval', '2')\n .option('--timeout <seconds>', 'Timeout', '120')\n .option('--until <target>', 'SUCCESS | FAILED | TERMINAL', 'TERMINAL')\n .option('--on-timeout <behavior>', 'fail | success', 'fail')\n .option('--json')\n .action(async (paymentHash, options) => {\n const json = Boolean(options.json);\n const intervalSeconds = parseInt(options.interval, 10);\n const timeoutSeconds = parseInt(options.timeout, 10);\n const until = String(options.until ?? 'TERMINAL')\n .trim()\n .toUpperCase();\n const onTimeout = String(options.onTimeout ?? 'fail')\n .trim()\n .toLowerCase();\n if (!['SUCCESS', 'FAILED', 'TERMINAL'].includes(until)) {\n if (json) {\n printJsonError({\n code: 'PAYMENT_WATCH_INPUT_INVALID',\n message: `Invalid --until value: ${options.until}. Expected SUCCESS, FAILED, or TERMINAL`,\n recoverable: true,\n suggestion: 'Use one of: SUCCESS, FAILED, TERMINAL.',\n details: { provided: options.until, expected: ['SUCCESS', 'FAILED', 'TERMINAL'] },\n });\n } else {\n console.error(\n `Error: Invalid --until value: ${options.until}. Expected SUCCESS, FAILED, or TERMINAL`,\n );\n }\n process.exit(1);\n }\n if (!['fail', 'success'].includes(onTimeout)) {\n if (json) {\n printJsonError({\n code: 'PAYMENT_WATCH_INPUT_INVALID',\n message: `Invalid --on-timeout value: ${options.onTimeout}. Expected fail or success`,\n recoverable: true,\n suggestion: 'Use `--on-timeout fail` or `--on-timeout success`.',\n details: { provided: options.onTimeout, expected: ['fail', 'success'] },\n });\n } else {\n console.error(\n `Error: Invalid --on-timeout value: ${options.onTimeout}. Expected fail or success`,\n );\n }\n process.exit(1);\n }\n const rpc = await createReadyRpcClient(config);\n const startedAt = Date.now();\n let lastStatus: string | undefined;\n\n while (Date.now() - startedAt < timeoutSeconds * 1000) {\n const paymentResult = await rpc.getPayment({ payment_hash: paymentHash as HexString });\n\n if (paymentResult.status !== lastStatus) {\n if (json) {\n printJsonEvent('status_transition', {\n statusTransition: {\n from: lastStatus ?? null,\n to: paymentResult.status,\n },\n payment: formatPaymentResult(paymentResult),\n });\n } else {\n console.log(`Status: ${lastStatus ?? '(initial)'} -> ${paymentResult.status}`);\n printPaymentDetailHuman(paymentResult);\n console.log('');\n }\n lastStatus = paymentResult.status;\n }\n\n const isSuccess = paymentResult.status === 'Success';\n const isFailed = paymentResult.status === 'Failed';\n const terminalReached =\n until === 'TERMINAL' ? isSuccess || isFailed : until === 'SUCCESS' ? isSuccess : isFailed;\n\n if (terminalReached) {\n if (json) {\n printJsonEvent('terminal', {\n paymentHash,\n terminalStatus: paymentResult.status,\n until,\n });\n }\n return;\n }\n\n if ((isSuccess || isFailed) && until !== 'TERMINAL') {\n if (json) {\n printJsonError({\n code: 'PAYMENT_WATCH_UNEXPECTED_TERMINAL',\n message: `Payment reached ${paymentResult.status} before requested --until ${until}`,\n recoverable: true,\n suggestion: 'Set `--until TERMINAL` or handle mismatched terminal state in caller.',\n details: { terminalStatus: paymentResult.status, until },\n });\n } else {\n console.error(\n `Error: Payment reached ${paymentResult.status} before requested --until ${until}`,\n );\n }\n process.exit(1);\n }\n\n await sleep(intervalSeconds * 1000);\n }\n\n if (onTimeout === 'success') {\n if (json) {\n printJsonEvent('terminal', {\n paymentHash,\n terminalStatus: 'Timeout',\n until,\n timeoutSeconds,\n });\n } else {\n console.log(\n `Timeout reached (${timeoutSeconds}s) and treated as success by --on-timeout=success.`,\n );\n }\n return;\n }\n\n if (json) {\n printJsonError({\n code: 'PAYMENT_WATCH_TIMEOUT',\n message: `Payment ${paymentHash} did not reach terminal state within ${timeoutSeconds}s`,\n recoverable: true,\n suggestion: 'Increase timeout, or continue polling using `payment get --json`.',\n details: { paymentHash, timeoutSeconds },\n });\n } else {\n console.error(\n `Error: Payment ${paymentHash} did not reach terminal state within ${timeoutSeconds}s`,\n );\n }\n process.exit(1);\n });\n\n payment\n .command('route')\n .description('Build a payment route through specified hops')\n .requiredOption('--hops <pubkeys>', 'Comma-separated list of node pubkeys forming the route')\n .option('--amount <ckb>', 'Amount in CKB to route')\n .option('--json')\n .action(async (options) => {\n const rpc = await createReadyRpcClient(config);\n const json = Boolean(options.json);\n const pubkeys = (options.hops as string).split(',').map((s: string) => s.trim());\n\n if (pubkeys.length === 0 || pubkeys.some((pk: string) => !pk)) {\n const msg = '--hops must be a non-empty comma-separated list of pubkeys';\n if (json) {\n printJsonError({\n code: 'PAYMENT_ROUTE_INPUT_INVALID',\n message: msg,\n recoverable: true,\n suggestion: 'Provide pubkeys: --hops 0xabc...,0xdef...',\n });\n } else {\n console.error(`Error: ${msg}`);\n }\n process.exit(1);\n }\n\n const hopsInfo = pubkeys.map((pubkey: string) => ({ pubkey: pubkey as HexString }));\n const amount = options.amount ? ckbToShannons(parseFloat(options.amount)) : undefined;\n\n const result = await rpc.buildRouter({\n hops_info: hopsInfo,\n amount,\n });\n\n if (json) {\n printJsonSuccess({ routerHops: result.router_hops });\n } else {\n console.log(`Route built: ${result.router_hops.length} hop(s)`);\n for (let i = 0; i < result.router_hops.length; i++) {\n const hop = result.router_hops[i];\n console.log(` #${i + 1}`);\n console.log(` Target: ${hop.target}`);\n console.log(\n ` Outpoint: ${hop.channel_outpoint.tx_hash}:${hop.channel_outpoint.index}`,\n );\n console.log(` Amount: ${shannonsToCkb(hop.amount_received)} CKB`);\n console.log(` Expiry: ${hop.incoming_tlc_expiry}`);\n }\n }\n });\n\n payment\n .command('send-route')\n .description('Send a payment using a pre-built route from `payment route`')\n .requiredOption(\n '--router <json>',\n 'JSON array of router hops (output of `payment route --json`)',\n )\n .option('--invoice <invoice>', 'Invoice to pay')\n .option('--payment-hash <hash>', 'Payment hash (for keysend)')\n .option('--keysend', 'Keysend mode')\n .option('--allow-self-payment', 'Allow self-payment for circular route rebalancing')\n .option('--dry-run', 'Simulate—do not actually send')\n .option('--json')\n .action(async (options) => {\n const rpc = await createReadyRpcClient(config);\n const json = Boolean(options.json);\n\n let router: RouterHop[];\n try {\n router = JSON.parse(options.router as string) as RouterHop[];\n } catch {\n const msg = '--router must be a valid JSON array of router hops';\n if (json) {\n printJsonError({\n code: 'PAYMENT_SEND_ROUTE_INPUT_INVALID',\n message: msg,\n recoverable: true,\n suggestion: 'Pipe --json output of `payment route` into this flag.',\n });\n } else {\n console.error(`Error: ${msg}`);\n }\n process.exit(1);\n }\n\n const result = await rpc.sendPaymentWithRouter({\n router,\n invoice: options.invoice as string | undefined,\n payment_hash: options.paymentHash as HexString | undefined,\n keysend: options.keysend ? true : undefined,\n allow_self_payment: options.allowSelfPayment ? true : undefined,\n dry_run: options.dryRun ? true : undefined,\n });\n\n const payload = {\n paymentHash: result.payment_hash,\n status:\n result.status === 'Success'\n ? 'success'\n : result.status === 'Failed'\n ? 'failed'\n : 'pending',\n feeCkb: shannonsToCkb(result.fee),\n failureReason: result.failed_error,\n dryRun: Boolean(options.dryRun),\n };\n\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log(options.dryRun ? 'Payment dry-run complete' : 'Payment sent via route');\n console.log(` Hash: ${payload.paymentHash}`);\n console.log(` Status: ${payload.status}`);\n console.log(` Fee: ${payload.feeCkb} CKB`);\n if (payload.failureReason) {\n console.log(` Error: ${payload.failureReason}`);\n }\n }\n });\n\n return payment;\n}\n\nfunction getJobPaymentHash(job: RuntimeJobRecord): string | undefined {\n const result = job.result as { paymentHash?: string } | undefined;\n return result?.paymentHash;\n}\n\nfunction getJobFeeCkb(job: RuntimeJobRecord): number {\n const result = job.result as { fee?: string } | undefined;\n return result?.fee ? shannonsToCkb(result.fee as HexString) : 0;\n}\n\nfunction getJobFailure(job: RuntimeJobRecord): string | undefined {\n const result = job.result as { failedError?: string } | undefined;\n return result?.failedError ?? job.error?.message;\n}\n","import { Command } from 'commander';\nimport type { CliConfig } from '../lib/config.js';\nimport { printJsonSuccess, printPeerListHuman } from '../lib/format.js';\nimport { createReadyRpcClient } from '../lib/rpc.js';\n\nfunction extractPeerIdFromMultiaddr(address: string): string | undefined {\n const match = address.match(/\\/p2p\\/([^/]+)$/);\n return match?.[1];\n}\n\nasync function waitForPeerConnected(\n rpc: Awaited<ReturnType<typeof createReadyRpcClient>>,\n peerId: string,\n timeoutMs: number,\n): Promise<boolean> {\n const start = Date.now();\n while (Date.now() - start < timeoutMs) {\n const peers = await rpc.listPeers();\n if (peers.peers.some((peer) => peer.peer_id === peerId)) {\n return true;\n }\n await new Promise((resolve) => setTimeout(resolve, 500));\n }\n return false;\n}\n\nexport function createPeerCommand(config: CliConfig): Command {\n const peer = new Command('peer').description('Peer management');\n\n peer\n .command('list')\n .option('--json')\n .action(async (options) => {\n const rpc = await createReadyRpcClient(config);\n const peers = await rpc.listPeers();\n if (options.json) {\n printJsonSuccess(peers);\n } else {\n printPeerListHuman(peers.peers);\n }\n });\n\n peer\n .command('connect')\n .argument('<multiaddr>')\n .option('--timeout <sec>', 'Wait timeout for peer to appear in peer list', '8')\n .option('--json')\n .action(async (address, options) => {\n const rpc = await createReadyRpcClient(config);\n const peerId = extractPeerIdFromMultiaddr(address);\n if (!peerId) {\n throw new Error('Invalid multiaddr: missing /p2p/<peerId> suffix');\n }\n\n await rpc.connectPeer({ address });\n const timeoutMs = Math.max(1, Number.parseInt(String(options.timeout), 10) || 8) * 1000;\n const connected = await waitForPeerConnected(rpc, peerId, timeoutMs);\n\n if (!connected) {\n throw new Error(\n `connect_peer accepted but peer not found in list within ${Math.floor(timeoutMs / 1000)}s (${peerId})`,\n );\n }\n\n if (options.json) {\n printJsonSuccess({ address, peerId, message: 'Connected' });\n } else {\n console.log('✅ Connected to peer');\n console.log(` Address: ${address}`);\n console.log(` Peer ID: ${peerId}`);\n }\n });\n\n peer\n .command('disconnect')\n .argument('<peerId>')\n .option('--json')\n .action(async (peerId, options) => {\n const rpc = await createReadyRpcClient(config);\n await rpc.disconnectPeer({ peer_id: peerId });\n\n if (options.json) {\n printJsonSuccess({ peerId, message: 'Disconnected' });\n } else {\n console.log('✅ Disconnected peer');\n console.log(` Peer ID: ${peerId}`);\n }\n });\n\n return peer;\n}\n","import { spawn } from 'node:child_process';\nimport { join, resolve } from 'node:path';\nimport type { Alert, AlertPriority, AlertType, RuntimeConfigInput } from '@fiber-pay/runtime';\nimport {\n alertPriorityOrder,\n formatRuntimeAlert,\n isAlertPriority,\n isAlertType,\n startRuntimeService,\n} from '@fiber-pay/runtime';\nimport { Command } from 'commander';\nimport type { CliConfig } from '../lib/config.js';\nimport { printJsonError, printJsonEvent, printJsonSuccess } from '../lib/format.js';\nimport { resolveLogDirForDateWithOptions } from '../lib/log-files.js';\nimport { parseBoolOption, parseIntegerOption } from '../lib/parse-options.js';\nimport { isProcessRunning } from '../lib/pid.js';\nimport {\n readRuntimeMeta,\n readRuntimePid,\n removeRuntimeFiles,\n writeRuntimeMeta,\n writeRuntimePid,\n} from '../lib/runtime-meta.js';\nimport {\n findListeningProcessByPort,\n isFiberRuntimeCommand,\n terminateProcess,\n} from '../lib/runtime-port.js';\n\ninterface RuntimeLogFilter {\n minPriority?: AlertPriority;\n types?: Set<AlertType>;\n}\n\nfunction formatRuntimeAlertLine(alert: Alert): string {\n return formatRuntimeAlert(alert);\n}\n\nfunction parseAlertPriorityOption(value: string | undefined): AlertPriority | undefined {\n if (!value) {\n return undefined;\n }\n const normalized = value.trim().toLowerCase();\n if (!isAlertPriority(normalized)) {\n throw new Error(`Invalid log-min-priority: ${value}. Expected critical|high|medium|low.`);\n }\n return normalized;\n}\n\nfunction parseAlertTypesOption(value: string | undefined): Set<AlertType> | undefined {\n if (!value) {\n return undefined;\n }\n\n const tokens = value\n .split(',')\n .map((token) => token.trim())\n .filter((token) => token.length > 0);\n\n if (tokens.length === 0) {\n return undefined;\n }\n\n const result = new Set<AlertType>();\n for (const token of tokens) {\n if (!isAlertType(token)) {\n throw new Error(`Invalid log-type: ${token}. Use runtime alert type names, comma-separated.`);\n }\n result.add(token);\n }\n\n return result;\n}\n\nfunction shouldPrintAlert(alert: Alert, filter: RuntimeLogFilter): boolean {\n if (filter.minPriority) {\n const minimumRank = alertPriorityOrder[filter.minPriority];\n if (alertPriorityOrder[alert.priority] < minimumRank) {\n return false;\n }\n }\n\n if (filter.types && filter.types.size > 0 && !filter.types.has(alert.type)) {\n return false;\n }\n\n return true;\n}\n\nfunction resolveRuntimeRecoveryListen(config: CliConfig): string {\n const meta = readRuntimeMeta(config.dataDir);\n return meta?.proxyListen ?? config.runtimeProxyListen ?? '127.0.0.1:8229';\n}\n\nexport function createRuntimeCommand(config: CliConfig): Command {\n const runtime = new Command('runtime').description('Polling monitor and alert runtime service');\n\n runtime\n .command('start')\n .description('Start runtime monitor service in foreground')\n .option('--daemon', 'Start runtime monitor in detached background mode')\n .option('--fiber-rpc-url <url>', 'Target fiber rpc URL (defaults to --rpc-url/global config)')\n .option('--proxy-listen <host:port>', 'Monitor proxy listen address')\n .option('--channel-poll-ms <ms>', 'Channel polling interval in milliseconds')\n .option('--invoice-poll-ms <ms>', 'Invoice polling interval in milliseconds')\n .option('--payment-poll-ms <ms>', 'Payment polling interval in milliseconds')\n .option('--peer-poll-ms <ms>', 'Peer polling interval in milliseconds')\n .option('--health-poll-ms <ms>', 'RPC health polling interval in milliseconds')\n .option('--include-closed <bool>', 'Monitor closed channels (true|false)')\n .option('--completed-ttl-seconds <seconds>', 'TTL for completed invoices/payments in tracker')\n .option('--state-file <path>', 'State file path for snapshots and history')\n .option('--alert-log-file <path>', 'Path to runtime alert JSONL log file (legacy static path)')\n .option('--alert-logs-base-dir <dir>', 'Base logs directory for daily-rotated alert files')\n .option('--flush-ms <ms>', 'State flush interval in milliseconds')\n .option('--webhook <url>', 'Webhook URL to receive alert POST payloads')\n .option('--websocket <host:port>', 'WebSocket alert broadcast listen address')\n .option(\n '--log-min-priority <priority>',\n 'Minimum runtime log priority (critical|high|medium|low)',\n )\n .option('--log-type <types>', 'Comma-separated runtime alert types to print')\n .option('--json')\n .action(async (options) => {\n const asJson = Boolean(options.json);\n const daemon = Boolean(options.daemon);\n const isRuntimeChild = process.env.FIBER_RUNTIME_CHILD === '1';\n const runtimeListen = String(\n options.proxyListen ?? config.runtimeProxyListen ?? '127.0.0.1:8229',\n );\n\n try {\n const existingPid = readRuntimePid(config.dataDir);\n if (\n existingPid &&\n isProcessRunning(existingPid) &&\n (!isRuntimeChild || existingPid !== process.pid)\n ) {\n const message = `Runtime already running (PID: ${existingPid})`;\n if (asJson) {\n printJsonError({\n code: 'RUNTIME_ALREADY_RUNNING',\n message,\n recoverable: true,\n suggestion: 'Run `fiber-pay runtime status` or `fiber-pay runtime stop` first.',\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n if (existingPid && !isProcessRunning(existingPid)) {\n removeRuntimeFiles(config.dataDir);\n }\n\n const discovered = findListeningProcessByPort(runtimeListen);\n if (discovered && (!existingPid || discovered.pid !== existingPid)) {\n if (isFiberRuntimeCommand(discovered.command)) {\n const terminated = await terminateProcess(discovered.pid);\n if (!terminated) {\n throw new Error(\n `Runtime port ${runtimeListen} is occupied by stale fiber-pay runtime PID ${discovered.pid} but termination failed.`,\n );\n }\n removeRuntimeFiles(config.dataDir);\n if (!asJson) {\n console.log(\n `Recovered stale runtime process on ${runtimeListen} (PID: ${discovered.pid}).`,\n );\n }\n } else if (discovered.command) {\n const details = discovered.command\n ? `PID ${discovered.pid} (${discovered.command})`\n : `PID ${discovered.pid}`;\n throw new Error(\n `Runtime proxy listen ${runtimeListen} is already in use by non-fiber-pay process: ${details}`,\n );\n } else {\n throw new Error(\n `Runtime proxy listen ${runtimeListen} is already in use by process PID ${discovered.pid}. ` +\n 'Unable to determine the owning command; inspect this PID manually before retrying.',\n );\n }\n }\n\n if (daemon && !isRuntimeChild) {\n const childArgv = process.argv.filter((arg) => arg !== '--daemon');\n const child = spawn(process.execPath, childArgv.slice(1), {\n detached: true,\n stdio: 'ignore',\n cwd: process.cwd(),\n env: {\n ...process.env,\n FIBER_RUNTIME_CHILD: '1',\n },\n });\n child.unref();\n\n const childPid = child.pid;\n if (!childPid) {\n throw new Error('Failed to spawn runtime daemon process');\n }\n\n writeRuntimePid(config.dataDir, childPid);\n\n if (asJson) {\n printJsonSuccess({\n daemon: true,\n pid: childPid,\n message: 'Runtime daemon starting',\n });\n } else {\n console.log(`Runtime daemon starting (PID: ${childPid})`);\n }\n return;\n }\n\n const runtimeConfig: RuntimeConfigInput = {\n fiberRpcUrl: String(options.fiberRpcUrl ?? config.rpcUrl),\n channelPollIntervalMs: parseIntegerOption(options.channelPollMs, 'channel-poll-ms'),\n invoicePollIntervalMs: parseIntegerOption(options.invoicePollMs, 'invoice-poll-ms'),\n paymentPollIntervalMs: parseIntegerOption(options.paymentPollMs, 'payment-poll-ms'),\n peerPollIntervalMs: parseIntegerOption(options.peerPollMs, 'peer-poll-ms'),\n healthPollIntervalMs: parseIntegerOption(options.healthPollMs, 'health-poll-ms'),\n includeClosedChannels: parseBoolOption(options.includeClosed, 'include-closed'),\n completedItemTtlSeconds: parseIntegerOption(\n options.completedTtlSeconds,\n 'completed-ttl-seconds',\n ),\n proxy: {\n enabled: true,\n listen: runtimeListen,\n },\n storage: {\n stateFilePath: options.stateFile\n ? resolve(String(options.stateFile))\n : resolve(config.dataDir, 'runtime-state.json'),\n flushIntervalMs: parseIntegerOption(options.flushMs, 'flush-ms'),\n },\n jobs: {\n enabled: true,\n dbPath: resolve(config.dataDir, 'runtime-jobs.db'),\n },\n };\n\n // Determine alert backend: prefer daily-file rotation, fall back to static file\n let alertLogsBaseDir: string | undefined;\n let alertLogFile: string | undefined;\n\n if (options.alertLogsBaseDir) {\n alertLogsBaseDir = resolve(String(options.alertLogsBaseDir));\n } else if (options.alertLogFile) {\n alertLogFile = resolve(String(options.alertLogFile));\n } else {\n alertLogsBaseDir = resolve(config.dataDir, 'logs');\n }\n\n const alerts: RuntimeConfigInput['alerts'] = [{ type: 'stdout' }];\n if (alertLogsBaseDir) {\n alerts.push({ type: 'daily-file', baseLogsDir: alertLogsBaseDir });\n } else if (alertLogFile) {\n alerts.push({ type: 'file', path: alertLogFile });\n }\n if (options.webhook) {\n alerts.push({ type: 'webhook', url: String(options.webhook) });\n }\n if (options.websocket) {\n alerts.push({ type: 'websocket', listen: String(options.websocket) });\n }\n runtimeConfig.alerts = alerts;\n\n const logFilter: RuntimeLogFilter = {\n minPriority: parseAlertPriorityOption(options.logMinPriority),\n types: parseAlertTypesOption(options.logType),\n };\n\n if (asJson) {\n printJsonEvent('runtime_starting', {\n fiberRpcUrl: runtimeConfig.fiberRpcUrl,\n proxyListen: runtimeConfig.proxy?.listen,\n });\n } else {\n console.log('Starting fiber runtime monitor...');\n }\n\n const runtime = await startRuntimeService(runtimeConfig);\n const status = runtime.service.getStatus();\n\n const logsBaseDir = alertLogsBaseDir ?? resolve(config.dataDir, 'logs');\n const todayLogDir = resolveLogDirForDateWithOptions(config.dataDir, undefined, {\n logsBaseDir,\n ensureExists: false,\n });\n const effectiveAlertLogPath = alertLogsBaseDir\n ? join(todayLogDir, 'runtime.alerts.jsonl')\n : (alertLogFile ?? join(todayLogDir, 'runtime.alerts.jsonl'));\n\n writeRuntimePid(config.dataDir, process.pid);\n writeRuntimeMeta(config.dataDir, {\n pid: process.pid,\n startedAt: status.startedAt,\n fiberRpcUrl: status.targetUrl,\n proxyListen: status.proxyListen,\n stateFilePath: runtimeConfig.storage?.stateFilePath,\n alertLogFilePath: effectiveAlertLogPath,\n fnnStdoutLogPath: join(todayLogDir, 'fnn.stdout.log'),\n fnnStderrLogPath: join(todayLogDir, 'fnn.stderr.log'),\n logsBaseDir,\n daemon: daemon || isRuntimeChild,\n });\n\n runtime.service.on('alert', (alert) => {\n if (!shouldPrintAlert(alert, logFilter)) {\n return;\n }\n\n if (asJson) {\n printJsonEvent('runtime_alert', alert);\n return;\n }\n console.log(formatRuntimeAlertLine(alert));\n });\n\n if (asJson) {\n printJsonSuccess({\n status: 'running',\n fiberRpcUrl: status.targetUrl,\n proxyListen: status.proxyListen,\n stateFilePath: runtimeConfig.storage?.stateFilePath,\n alertLogFile: effectiveAlertLogPath,\n logsBaseDir,\n });\n printJsonEvent('runtime_started', status);\n } else {\n console.log(`Fiber RPC: ${status.targetUrl}`);\n console.log(`Proxy listen: ${status.proxyListen}`);\n console.log(`State file: ${runtimeConfig.storage?.stateFilePath}`);\n console.log(`Logs dir: ${logsBaseDir}`);\n console.log(`Alert log: ${effectiveAlertLogPath}`);\n console.log('Runtime monitor is running. Press Ctrl+C to stop.');\n }\n\n const signal = await runtime.waitForShutdownSignal();\n\n if (asJson) {\n printJsonEvent('runtime_stopping', { signal });\n } else {\n console.log(`Stopping runtime monitor on ${signal}...`);\n }\n\n await runtime.stop();\n removeRuntimeFiles(config.dataDir);\n\n if (asJson) {\n printJsonEvent('runtime_stopped', { signal });\n } else {\n console.log('Runtime monitor stopped.');\n }\n } catch (error) {\n removeRuntimeFiles(config.dataDir);\n const message = error instanceof Error ? error.message : String(error);\n if (asJson) {\n printJsonError({\n code: 'RUNTIME_START_FAILED',\n message,\n recoverable: true,\n suggestion: 'Check RPC URL reachability and runtime option values, then retry.',\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n });\n\n runtime\n .command('status')\n .description('Show runtime process and health status')\n .option('--json')\n .action(async (options) => {\n const asJson = Boolean(options.json);\n let pid = readRuntimePid(config.dataDir);\n const meta = readRuntimeMeta(config.dataDir);\n const recoveryListen = resolveRuntimeRecoveryListen(config);\n\n if (!pid) {\n const fallback = findListeningProcessByPort(recoveryListen);\n if (fallback && isFiberRuntimeCommand(fallback.command)) {\n pid = fallback.pid;\n writeRuntimePid(config.dataDir, pid);\n } else if (fallback && fallback.command) {\n const details = fallback.command\n ? `PID ${fallback.pid} (${fallback.command})`\n : `PID ${fallback.pid}`;\n if (asJson) {\n printJsonError({\n code: 'RUNTIME_PORT_IN_USE',\n message: `Runtime proxy port is in use by non-fiber-pay process: ${details}`,\n recoverable: true,\n suggestion: 'Stop that process or use a different --proxy-listen port.',\n });\n } else {\n console.log(`Runtime proxy port is in use by non-fiber-pay process: ${details}`);\n }\n process.exit(1);\n } else if (fallback) {\n const message =\n `Runtime proxy port is in use by process PID ${fallback.pid}. ` +\n 'The owning command could not be determined; inspect this PID manually.';\n if (asJson) {\n printJsonError({\n code: 'RUNTIME_PORT_IN_USE',\n message,\n recoverable: true,\n suggestion: 'Inspect the PID owner manually or use a different --proxy-listen port.',\n });\n } else {\n console.log(message);\n }\n process.exit(1);\n }\n }\n\n if (!pid) {\n if (asJson) {\n printJsonError({\n code: 'RUNTIME_NOT_RUNNING',\n message: 'Runtime PID file not found.',\n recoverable: true,\n suggestion: 'Start runtime with `fiber-pay runtime start --daemon`.',\n });\n } else {\n console.log('Runtime is not running.');\n }\n process.exit(1);\n }\n\n const running = isProcessRunning(pid);\n if (!running) {\n removeRuntimeFiles(config.dataDir);\n if (asJson) {\n printJsonError({\n code: 'RUNTIME_NOT_RUNNING',\n message: `Runtime process ${pid} is not running. Stale runtime files cleaned.`,\n recoverable: true,\n suggestion: 'Start runtime again with `fiber-pay runtime start`.',\n details: { pid, staleFilesCleaned: true },\n });\n } else {\n console.log(`Runtime process ${pid} is not running. Stale runtime files cleaned.`);\n }\n process.exit(1);\n }\n\n let rpcStatus: unknown;\n if (meta?.proxyListen ?? recoveryListen) {\n try {\n const response = await fetch(\n `http://${meta?.proxyListen ?? recoveryListen}/monitor/status`,\n );\n if (response.ok) {\n rpcStatus = await response.json();\n }\n } catch {\n rpcStatus = undefined;\n }\n }\n\n const payload = {\n running: true,\n pid,\n meta,\n proxyStatus: rpcStatus,\n };\n\n if (asJson) {\n printJsonSuccess(payload);\n } else {\n console.log(`Runtime is running (PID: ${pid})`);\n if (meta?.fiberRpcUrl) {\n console.log(`Fiber RPC: ${meta.fiberRpcUrl}`);\n }\n if (meta?.proxyListen) {\n console.log(`Proxy listen: ${meta.proxyListen}`);\n }\n }\n });\n\n runtime\n .command('stop')\n .description('Stop runtime process by PID')\n .option('--json')\n .action(async (options) => {\n const asJson = Boolean(options.json);\n let pid = readRuntimePid(config.dataDir);\n const recoveryListen = resolveRuntimeRecoveryListen(config);\n\n if (!pid) {\n const fallback = findListeningProcessByPort(recoveryListen);\n if (fallback && isFiberRuntimeCommand(fallback.command)) {\n pid = fallback.pid;\n writeRuntimePid(config.dataDir, pid);\n } else if (fallback && fallback.command) {\n const details = fallback.command\n ? `PID ${fallback.pid} (${fallback.command})`\n : `PID ${fallback.pid}`;\n if (asJson) {\n printJsonError({\n code: 'RUNTIME_PORT_IN_USE',\n message: `Runtime proxy port is in use by non-fiber-pay process: ${details}`,\n recoverable: true,\n suggestion:\n 'Stop that process manually; it is not managed by fiber-pay runtime PID files.',\n });\n } else {\n console.log(`Runtime proxy port is in use by non-fiber-pay process: ${details}`);\n }\n process.exit(1);\n } else if (fallback) {\n const message =\n `Runtime proxy port is in use by process PID ${fallback.pid}. ` +\n 'The owning command could not be determined; inspect this PID manually.';\n if (asJson) {\n printJsonError({\n code: 'RUNTIME_PORT_IN_USE',\n message,\n recoverable: true,\n suggestion:\n 'Inspect the PID owner manually; it may not be managed by fiber-pay runtime PID files.',\n });\n } else {\n console.log(message);\n }\n process.exit(1);\n }\n }\n\n if (!pid) {\n if (asJson) {\n printJsonError({\n code: 'RUNTIME_NOT_RUNNING',\n message: 'Runtime PID file not found.',\n recoverable: true,\n suggestion: 'Start runtime first with `fiber-pay runtime start --daemon`.',\n });\n } else {\n console.log('Runtime is not running.');\n }\n process.exit(1);\n }\n\n if (!isProcessRunning(pid)) {\n removeRuntimeFiles(config.dataDir);\n if (asJson) {\n printJsonError({\n code: 'RUNTIME_NOT_RUNNING',\n message: `Runtime process ${pid} is not running. Stale runtime files cleaned.`,\n recoverable: true,\n suggestion: 'Start runtime again if needed.',\n details: { pid, staleFilesCleaned: true },\n });\n } else {\n console.log(`Runtime process ${pid} is not running. Stale runtime files cleaned.`);\n }\n process.exit(1);\n }\n\n const terminated = await terminateProcess(pid);\n if (!terminated) {\n if (asJson) {\n printJsonError({\n code: 'RUNTIME_STOP_FAILED',\n message: `Failed to terminate runtime process ${pid}.`,\n recoverable: true,\n suggestion: `Try stopping PID ${pid} manually and rerun runtime stop.`,\n });\n } else {\n console.log(`Failed to terminate runtime process ${pid}.`);\n }\n process.exit(1);\n }\n\n removeRuntimeFiles(config.dataDir);\n if (asJson) {\n printJsonSuccess({ stopped: true, pid });\n } else {\n console.log(`Runtime stopped (PID: ${pid})`);\n }\n });\n\n return runtime;\n}\n","export function parseIntegerOption(value: string | undefined, name: string): number | undefined {\n if (value === undefined) {\n return undefined;\n }\n const parsed = Number.parseInt(value, 10);\n if (!Number.isInteger(parsed) || parsed <= 0) {\n throw new Error(`Invalid ${name}: ${value}. Expected positive integer.`);\n }\n return parsed;\n}\n\nexport function parseBoolOption(value: string | undefined, name: string): boolean | undefined {\n if (value === undefined) {\n return undefined;\n }\n const normalized = value.toLowerCase();\n if (normalized === 'true') return true;\n if (normalized === 'false') return false;\n throw new Error(`Invalid ${name}: ${value}. Expected true|false.`);\n}\n","import { Command } from 'commander';\nimport { CLI_COMMIT, CLI_VERSION } from '../lib/build-info.js';\nimport { printJsonSuccess } from '../lib/format.js';\n\nexport function createVersionCommand(): Command {\n return new Command('version')\n .description('Show CLI version and commit id')\n .option('--json', 'Output JSON')\n .action((options: { json?: boolean }) => {\n const payload = {\n version: CLI_VERSION,\n commit: CLI_COMMIT,\n };\n\n if (options.json) {\n printJsonSuccess(payload);\n return;\n }\n\n console.log(`Version: ${payload.version}`);\n console.log(`Commit: ${payload.commit}`);\n });\n}\n","export const CLI_VERSION = process.env.FIBER_PAY_CLI_VERSION ?? 'unknown';\nexport const CLI_COMMIT = process.env.FIBER_PAY_CLI_COMMIT ?? 'unknown';\n","const GLOBAL_OPTIONS_WITH_VALUE = new Set([\n '--profile',\n '--data-dir',\n '--rpc-url',\n '--network',\n '--key-password',\n '--binary-path',\n]);\n\nfunction isOptionToken(token: string): boolean {\n return token.startsWith('-') && token !== '-';\n}\n\nfunction hasInlineValue(token: string): boolean {\n return token.includes('=');\n}\n\nfunction getFirstPositional(argv: string[]): string | undefined {\n for (let index = 2; index < argv.length; index++) {\n const token = argv[index];\n\n if (token === '--') {\n return argv[index + 1];\n }\n\n if (!isOptionToken(token)) {\n return token;\n }\n\n if (GLOBAL_OPTIONS_WITH_VALUE.has(token) && !hasInlineValue(token)) {\n const next = argv[index + 1];\n if (next && !isOptionToken(next)) {\n index++;\n }\n }\n }\n\n return undefined;\n}\n\nfunction hasTopLevelVersionFlag(argv: string[]): boolean {\n for (let index = 2; index < argv.length; index++) {\n const token = argv[index];\n if (token === '--') {\n return false;\n }\n if (token === '--version' || token === '-v') {\n return true;\n }\n }\n return false;\n}\n\nexport function isTopLevelVersionRequest(argv: string[]): boolean {\n return !getFirstPositional(argv) && hasTopLevelVersionFlag(argv);\n}\n"],"mappings":"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","names":["join","Command","binaryPath","installDir","ckbToShannons","Command","resolve","existsSync","join","existsSync","readFileSync","unlinkSync","writeFileSync","join","shannonsToCkb","shannonsToCkb","Command","ckbToShannons","payload","existsSync","readFileSync","writeFileSync","Command","existsSync","readFileSync","writeFileSync","join","join","existsSync","readFileSync","writeFileSync","explicitFlags","lowered","existsSync","readFileSync","Command","writeFileSync","shannonsToCkb","toHex","Command","shannonsToCkb","Command","toHex","ckbToShannons","shannonsToCkb","toHex","Command","Command","ckbToShannons","toHex","result","payload","shannonsToCkb","output","existsSync","Command","existsSync","mkdirSync","join","dir","Command","existsSync","existsSync","statSync","join","Command","DATE_DIR_PATTERN","Command","join","date","existsSync","statSync","resolve","Command","mkdirSync","join","existsSync","readFileSync","dirname","BinaryManager","dirname","BinaryManager","spawnSync","spawnSync","resolve","join","mkdirSync","resolve","existsSync","ChannelState","existsSync","ChannelState","resolve","BinaryManager","MigrationManager","BinaryManager","MigrationManager","showProgress","Command","ckbToShannons","shannonsToCkb","Command","Command","ckbToShannons","payload","shannonsToCkb","Command","resolve","Command","spawn","join","formatRuntimeAlert","startRuntimeService","Command","formatRuntimeAlert","Command","spawn","runtime","startRuntimeService","join","Command","Command","join","Command"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/commands/binary.ts","../src/lib/binary-path.ts","../src/lib/node-runtime-daemon.ts","../src/lib/format.ts","../src/commands/channel.ts","../src/lib/async.ts","../src/lib/rpc.ts","../src/lib/pid.ts","../src/lib/runtime-meta.ts","../src/lib/runtime-jobs.ts","../src/commands/rebalance.ts","../src/commands/config.ts","../src/lib/config.ts","../src/lib/config-templates.ts","../src/commands/graph.ts","../src/commands/invoice.ts","../src/commands/job.ts","../src/lib/log-files.ts","../src/commands/logs.ts","../src/commands/node.ts","../src/lib/node-info.ts","../src/lib/node-network.ts","../src/lib/node-start.ts","../src/lib/bootnode.ts","../src/lib/node-migration.ts","../src/lib/migration-utils.ts","../src/lib/runtime-port.ts","../src/lib/node-status.ts","../src/lib/node-recommendation.ts","../src/lib/node-rpc.ts","../src/lib/node-stop.ts","../src/lib/node-upgrade.ts","../src/commands/payment.ts","../src/commands/peer.ts","../src/commands/runtime.ts","../src/lib/parse-options.ts","../src/commands/version.ts","../src/lib/build-info.ts","../src/commands/wallet.ts","../src/lib/wallet-address.ts","../src/lib/wallet-balance.ts","../src/lib/argv.ts"],"sourcesContent":["import { join } from 'node:path';\nimport { Command } from 'commander';\nimport { createBinaryCommand } from './commands/binary.js';\nimport { createChannelCommand } from './commands/channel.js';\nimport { createConfigCommand } from './commands/config.js';\nimport { createGraphCommand } from './commands/graph.js';\nimport { createInvoiceCommand } from './commands/invoice.js';\nimport { createJobCommand } from './commands/job.js';\nimport { createLogsCommand } from './commands/logs.js';\nimport { createNodeCommand } from './commands/node.js';\nimport { createPaymentCommand } from './commands/payment.js';\nimport { createPeerCommand } from './commands/peer.js';\nimport { createRuntimeCommand } from './commands/runtime.js';\nimport { createVersionCommand } from './commands/version.js';\nimport { createWalletCommand } from './commands/wallet.js';\nimport { isTopLevelVersionRequest } from './lib/argv.js';\nimport { CLI_COMMIT, CLI_VERSION } from './lib/build-info.js';\nimport { getEffectiveConfig } from './lib/config.js';\nimport { printJsonError } from './lib/format.js';\n\nfunction shouldOutputJson(): boolean {\n return process.argv.includes('--json');\n}\n\nfunction getFlagValue(argv: string[], index: number): string | undefined {\n const value = argv[index + 1];\n if (!value || value.startsWith('-')) {\n return undefined;\n }\n return value;\n}\n\n/** Tracks which config keys were explicitly set via CLI flags. */\nconst explicitFlags = new Set<string>();\n\nfunction applyGlobalOverrides(argv: string[]): void {\n let explicitDataDir = false;\n let profileName: string | undefined;\n explicitFlags.clear();\n\n for (let index = 0; index < argv.length; index++) {\n const arg = argv[index];\n switch (arg) {\n case '--profile': {\n const value = getFlagValue(argv, index);\n if (value) profileName = value;\n break;\n }\n case '--data-dir': {\n const value = getFlagValue(argv, index);\n if (value) {\n process.env.FIBER_DATA_DIR = value;\n explicitDataDir = true;\n explicitFlags.add('dataDir');\n }\n break;\n }\n case '--rpc-url': {\n const value = getFlagValue(argv, index);\n if (value) {\n process.env.FIBER_RPC_URL = value;\n explicitFlags.add('rpcUrl');\n }\n break;\n }\n case '--rpc-biscuit-token': {\n const value = getFlagValue(argv, index);\n if (value) {\n process.env.FIBER_RPC_BISCUIT_TOKEN = value;\n explicitFlags.add('rpcBiscuitToken');\n }\n break;\n }\n case '--network': {\n const value = getFlagValue(argv, index);\n if (value) {\n process.env.FIBER_NETWORK = value;\n explicitFlags.add('network');\n }\n break;\n }\n case '--key-password': {\n const value = getFlagValue(argv, index);\n if (value) {\n process.env.FIBER_KEY_PASSWORD = value;\n explicitFlags.add('keyPassword');\n }\n break;\n }\n case '--binary-path': {\n const value = getFlagValue(argv, index);\n if (value) {\n process.env.FIBER_BINARY_PATH = value;\n explicitFlags.add('binaryPath');\n }\n break;\n }\n case '--runtime-proxy-listen':\n case '--proxy-listen': {\n const value = getFlagValue(argv, index);\n if (value) {\n process.env.FIBER_RUNTIME_PROXY_LISTEN = value;\n explicitFlags.add('runtimeProxyListen');\n }\n break;\n }\n default:\n break;\n }\n }\n\n if (!explicitDataDir && profileName) {\n const homeDir = process.env.HOME ?? process.cwd();\n process.env.FIBER_DATA_DIR = join(homeDir, '.fiber-pay', 'profiles', profileName);\n }\n}\n\nfunction printFatal(error: unknown): void {\n const message = error instanceof Error ? error.message : String(error);\n const commanderCode =\n error && typeof error === 'object' && 'code' in error\n ? String((error as { code: unknown }).code)\n : undefined;\n\n if (shouldOutputJson()) {\n printJsonError({\n code: commanderCode ?? 'CLI_FATAL',\n message,\n recoverable: !commanderCode || commanderCode.startsWith('commander.'),\n suggestion: commanderCode?.startsWith('commander.')\n ? 'Run the command with --help and fix invalid arguments.'\n : 'Inspect command arguments and environment, then retry.',\n });\n } else {\n if (commanderCode?.startsWith('commander.')) {\n return;\n }\n console.error('Fatal error:', message);\n }\n}\n\nasync function main(): Promise<void> {\n const argv = process.argv;\n\n if (isTopLevelVersionRequest(argv)) {\n console.log(`${CLI_VERSION} (${CLI_COMMIT})`);\n return;\n }\n\n applyGlobalOverrides(argv);\n const config = getEffectiveConfig(explicitFlags).config;\n\n const program = new Command();\n program\n .name('fiber-pay')\n .description('AI Agent Payment SDK for CKB Lightning Network')\n .option('--profile <name>', 'Use profile at ~/.fiber-pay/profiles/<name>')\n .option('--data-dir <path>', 'Override data directory for all commands')\n .option('--rpc-url <url>', 'Override RPC URL for all commands')\n .option('--rpc-biscuit-token <token>', 'Set RPC Authorization Bearer token for all commands')\n .option('--network <network>', 'Override network for all commands (testnet|mainnet)')\n .option('--key-password <password>', 'Override key password for all commands')\n .option('--binary-path <path>', 'Override fiber binary path for all commands')\n .showHelpAfterError()\n .showSuggestionAfterError();\n\n program.exitOverride();\n program.configureOutput({\n writeOut: (str) => process.stdout.write(str),\n writeErr: (str) => {\n if (!shouldOutputJson()) {\n process.stderr.write(str);\n }\n },\n });\n\n program.addCommand(createNodeCommand(config));\n program.addCommand(createChannelCommand(config));\n program.addCommand(createInvoiceCommand(config));\n program.addCommand(createPaymentCommand(config));\n program.addCommand(createJobCommand(config));\n program.addCommand(createLogsCommand(config));\n program.addCommand(createPeerCommand(config));\n program.addCommand(createGraphCommand(config));\n program.addCommand(createBinaryCommand(config));\n program.addCommand(createConfigCommand(config));\n program.addCommand(createRuntimeCommand(config));\n program.addCommand(createVersionCommand());\n program.addCommand(createWalletCommand(config));\n\n await program.parseAsync(argv);\n}\n\nmain().catch((error) => {\n const commanderCode =\n error && typeof error === 'object' && 'code' in error\n ? String((error as { code: unknown }).code)\n : undefined;\n const commanderExitCode =\n error && typeof error === 'object' && 'exitCode' in error\n ? Number((error as { exitCode: unknown }).exitCode)\n : undefined;\n\n printFatal(error);\n\n if (commanderCode?.startsWith('commander.') && commanderExitCode === 0) {\n process.exit(0);\n }\n\n process.exit(1);\n});\n","import { DEFAULT_FIBER_VERSION, type DownloadProgress, downloadFiberBinary } from '@fiber-pay/node';\nimport { Command } from 'commander';\nimport {\n getBinaryDetails,\n getBinaryManagerInstallDirOrThrow,\n resolveBinaryPath,\n} from '../lib/binary-path.js';\nimport type { CliConfig } from '../lib/config.js';\nimport { printJsonError, printJsonSuccess } from '../lib/format.js';\n\nfunction showProgress(progress: DownloadProgress): void {\n const percent = progress.percent !== undefined ? ` (${progress.percent}%)` : '';\n process.stdout.write(`\\r[${progress.phase}]${percent} ${progress.message}`.padEnd(80));\n if (progress.phase === 'installing') {\n console.log();\n }\n}\n\nexport function createBinaryCommand(config: CliConfig): Command {\n const binary = new Command('binary').description('Fiber binary management');\n\n binary\n .command('download')\n .option('--version <version>', 'Fiber binary version', DEFAULT_FIBER_VERSION)\n .option('--force', 'Force re-download')\n .option('--json')\n .action(async (options) => {\n const resolvedBinary = resolveBinaryPath(config);\n let installDir: string;\n try {\n installDir = getBinaryManagerInstallDirOrThrow(resolvedBinary);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (options.json) {\n printJsonError({\n code: 'BINARY_PATH_INCOMPATIBLE',\n message,\n recoverable: true,\n suggestion:\n 'Use `fiber-pay config profile unset binaryPath` or set binaryPath to a standard fnn filename in the target directory.',\n });\n } else {\n console.error(`❌ ${message}`);\n }\n process.exit(1);\n }\n\n const info = await downloadFiberBinary({\n installDir,\n version: options.version,\n force: Boolean(options.force),\n onProgress: options.json ? undefined : showProgress,\n });\n\n if (options.json) {\n printJsonSuccess({\n ...info,\n source: resolvedBinary.source,\n resolvedPath: resolvedBinary.binaryPath,\n });\n } else {\n console.log('\\n✅ Binary installed successfully!');\n console.log(` Path: ${info.path}`);\n console.log(` Version: ${info.version}`);\n console.log(` Ready: ${info.ready ? 'yes' : 'no'}`);\n }\n });\n\n binary\n .command('info')\n .option('--json')\n .action(async (options) => {\n const { resolvedBinary, info } = await getBinaryDetails(config);\n\n if (options.json) {\n printJsonSuccess({\n ...info,\n source: resolvedBinary.source,\n resolvedPath: resolvedBinary.binaryPath,\n });\n } else {\n console.log(info.ready ? '✅ Binary is ready' : '❌ Binary not found or not executable');\n console.log(` Path: ${info.path}`);\n console.log(` Version: ${info.version}`);\n }\n });\n\n return binary;\n}\n","import { dirname, join } from 'node:path';\nimport { type BinaryInfo, BinaryManager, getFiberBinaryInfo } from '@fiber-pay/node';\nimport type { CliConfig } from './config.js';\nimport { getCustomBinaryState } from './node-runtime-daemon.js';\n\nexport interface ResolvedBinaryPath {\n binaryPath: string;\n installDir: string | null;\n managedPath: string;\n managedByBinaryManager: boolean;\n source: 'configured-path' | 'profile-managed';\n}\n\nexport function getProfileBinaryInstallDir(dataDir: string): string {\n return join(dataDir, 'bin');\n}\n\nexport function getProfileManagedBinaryPath(dataDir: string): string {\n return new BinaryManager(getProfileBinaryInstallDir(dataDir)).getBinaryPath();\n}\n\nfunction validateConfiguredBinaryPath(binaryPath: string): string {\n const value = binaryPath.trim();\n if (!value) {\n throw new Error('Configured binaryPath cannot be empty');\n }\n if (value.includes('\\0')) {\n throw new Error('Configured binaryPath contains an invalid null byte');\n }\n return value;\n}\n\nexport function resolveBinaryPath(config: CliConfig): ResolvedBinaryPath {\n const managedPath = getProfileManagedBinaryPath(config.dataDir);\n\n if (config.binaryPath) {\n const binaryPath = validateConfiguredBinaryPath(config.binaryPath);\n const installDir = dirname(binaryPath);\n const expectedPath = new BinaryManager(installDir).getBinaryPath();\n const managedByBinaryManager = expectedPath === binaryPath;\n const source: ResolvedBinaryPath['source'] =\n binaryPath === managedPath ? 'profile-managed' : 'configured-path';\n\n return {\n binaryPath,\n installDir: managedByBinaryManager ? installDir : null,\n managedPath,\n managedByBinaryManager,\n source,\n };\n }\n\n const installDir = getProfileBinaryInstallDir(config.dataDir);\n const binaryPath = managedPath;\n return {\n binaryPath,\n installDir,\n managedPath,\n managedByBinaryManager: true,\n source: 'profile-managed',\n };\n}\n\nexport function getBinaryManagerInstallDirOrThrow(resolvedBinary: ResolvedBinaryPath): string {\n if (resolvedBinary.installDir) {\n return resolvedBinary.installDir;\n }\n\n throw new Error(\n `Configured binaryPath \"${resolvedBinary.binaryPath}\" is incompatible with BinaryManager-managed path naming. ` +\n `BinaryManager expects \"${new BinaryManager(dirname(resolvedBinary.binaryPath)).getBinaryPath()}\". ` +\n 'Set binaryPath to a standard managed name (fnn/fnn.exe) in the target directory, or unset binaryPath to use the profile-managed binary.',\n );\n}\n\nexport async function getBinaryDetails(config: CliConfig): Promise<{\n resolvedBinary: ResolvedBinaryPath;\n info: BinaryInfo | ReturnType<typeof getCustomBinaryState>;\n}> {\n const resolvedBinary = resolveBinaryPath(config);\n const info = resolvedBinary.installDir\n ? await getFiberBinaryInfo(resolvedBinary.installDir)\n : getCustomBinaryState(resolvedBinary.binaryPath);\n\n return { resolvedBinary, info };\n}\n","import { spawnSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\n\nexport function getCustomBinaryState(binaryPath: string): {\n path: string;\n ready: boolean;\n version: string;\n} {\n const exists = existsSync(binaryPath);\n if (!exists) {\n return { path: binaryPath, ready: false, version: 'unknown' };\n }\n\n try {\n const result = spawnSync(binaryPath, ['--version'], { encoding: 'utf-8' });\n if (result.status !== 0) {\n return { path: binaryPath, ready: false, version: 'unknown' };\n }\n const output = `${result.stdout ?? ''}${result.stderr ?? ''}`.trim();\n const firstLine = output.split('\\n').find((line) => line.trim().length > 0) ?? 'unknown';\n return { path: binaryPath, ready: true, version: firstLine.trim() };\n } catch {\n return { path: binaryPath, ready: false, version: 'unknown' };\n }\n}\n\nexport function getBinaryVersion(binaryPath: string): string {\n try {\n const result = spawnSync(binaryPath, ['--version'], { encoding: 'utf-8' });\n if (result.status !== 0) {\n return 'unknown';\n }\n const output = `${result.stdout ?? ''}${result.stderr ?? ''}`.trim();\n if (!output) {\n return 'unknown';\n }\n const firstLine = output.split('\\n').find((line) => line.trim().length > 0);\n return firstLine?.trim() ?? 'unknown';\n } catch {\n return 'unknown';\n }\n}\n\nfunction getCliEntrypoint(): string {\n const entrypoint = process.argv[1];\n if (!entrypoint) {\n throw new Error('Unable to resolve CLI entrypoint path');\n }\n return entrypoint;\n}\n\nexport function startRuntimeDaemonFromNode(params: {\n dataDir: string;\n rpcUrl: string;\n proxyListen: string;\n stateFilePath: string;\n alertLogsBaseDir: string;\n}): { ok: true } | { ok: false; message: string } {\n const cliEntrypoint = getCliEntrypoint();\n const result = spawnSync(\n process.execPath,\n [\n cliEntrypoint,\n '--data-dir',\n params.dataDir,\n '--rpc-url',\n params.rpcUrl,\n 'runtime',\n 'start',\n '--daemon',\n '--fiber-rpc-url',\n params.rpcUrl,\n '--proxy-listen',\n params.proxyListen,\n '--state-file',\n params.stateFilePath,\n '--alert-logs-base-dir',\n params.alertLogsBaseDir,\n '--json',\n ],\n { encoding: 'utf-8' },\n );\n\n if (result.status === 0) {\n return { ok: true };\n }\n\n const stderr = (result.stderr ?? '').trim();\n const stdout = (result.stdout ?? '').trim();\n const details = stderr || stdout || `exit code ${result.status ?? 'unknown'}`;\n return { ok: false, message: details };\n}\n\nexport function stopRuntimeDaemonFromNode(params: { dataDir: string; rpcUrl: string }): void {\n const cliEntrypoint = getCliEntrypoint();\n spawnSync(\n process.execPath,\n [\n cliEntrypoint,\n '--data-dir',\n params.dataDir,\n '--rpc-url',\n params.rpcUrl,\n 'runtime',\n 'stop',\n '--json',\n ],\n { encoding: 'utf-8' },\n );\n}\n","import {\n type Channel,\n ChannelState,\n type CkbInvoice,\n type GetPaymentResult,\n shannonsToCkb,\n toHex,\n} from '@fiber-pay/sdk';\n\nconst SHANNONS_PER_CKB = 100_000_000n;\n\nexport function truncateMiddle(value: string, start = 10, end = 8): string {\n if (!value || value.length <= start + end + 3) {\n return value;\n }\n return `${value.slice(0, start)}...${value.slice(-end)}`;\n}\n\nexport function sanitizeForTerminal(value: unknown): string {\n const input = String(value ?? '');\n let output = '';\n\n for (let i = 0; i < input.length; i++) {\n const code = input.charCodeAt(i);\n\n // Strip ANSI escape sequences, including CSI forms like ESC [ ... m.\n if (code === 0x1b) {\n i++;\n if (i >= input.length) break;\n\n if (input.charCodeAt(i) === 0x5b) {\n i++;\n while (i < input.length) {\n const csiCode = input.charCodeAt(i);\n if (csiCode >= 0x40 && csiCode <= 0x7e) {\n break;\n }\n i++;\n }\n }\n continue;\n }\n\n // Normalize tabs/newlines and drop other control characters.\n if (code === 0x09 || code === 0x0a || code === 0x0d) {\n output += ' ';\n continue;\n }\n if ((code >= 0x00 && code <= 0x08) || (code >= 0x0b && code <= 0x1f)) {\n continue;\n }\n if (code >= 0x7f && code <= 0x9f) {\n continue;\n }\n\n output += input[i];\n }\n\n return output;\n}\n\nexport function formatShannonsAsCkb(shannons: bigint | string, fractionDigits = 8): string {\n const value = typeof shannons === 'bigint' ? shannons : BigInt(shannons);\n const sign = value < 0n ? '-' : '';\n const abs = value < 0n ? -value : value;\n const safeDigits = Math.max(0, Math.min(8, Math.trunc(fractionDigits)));\n const multiplier = 10n ** BigInt(safeDigits);\n const scaled = (abs * multiplier + SHANNONS_PER_CKB / 2n) / SHANNONS_PER_CKB;\n const whole = scaled / multiplier;\n\n if (safeDigits === 0) {\n return `${sign}${whole}`;\n }\n\n const fraction = (scaled % multiplier).toString().padStart(safeDigits, '0');\n return `${sign}${whole}.${fraction}`;\n}\n\nexport function parseHexTimestampMs(hexTimestamp: string): number | null {\n if (!hexTimestamp) return null;\n try {\n const raw = Number(BigInt(hexTimestamp));\n if (!Number.isFinite(raw) || raw <= 0) return null;\n return raw > 1_000_000_000_000 ? raw : raw * 1000;\n } catch {\n return null;\n }\n}\n\nexport function formatAge(whenMs: number | null): string {\n if (!whenMs) return 'unknown';\n const diff = Date.now() - whenMs;\n if (diff < 0) return 'just now';\n\n const seconds = Math.floor(diff / 1000);\n if (seconds < 60) return `${seconds}s ago`;\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ${minutes % 60}m ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ${hours % 24}h ago`;\n}\n\nexport function stateLabel(state: ChannelState): string {\n switch (state) {\n case ChannelState.NegotiatingFunding:\n return '🔄 Negotiating Funding';\n case ChannelState.CollaboratingFundingTx:\n return '🧩 Collaborating Funding Tx';\n case ChannelState.SigningCommitment:\n return '✍️ Signing Commitment';\n case ChannelState.AwaitingTxSignatures:\n return '⏳ Awaiting Tx Signatures';\n case ChannelState.AwaitingChannelReady:\n return '⏳ Awaiting Channel Ready';\n case ChannelState.ChannelReady:\n return '✅ Channel Ready';\n case ChannelState.ShuttingDown:\n return '🛑 Shutting Down';\n case ChannelState.Closed:\n return '❌ Closed';\n default:\n return state;\n }\n}\n\nexport function parseChannelState(input: string | undefined): ChannelState | undefined {\n if (!input) return undefined;\n const trimmed = input.trim();\n const legacy = trimmed.toUpperCase();\n const normalizedInput = trimmed.replace(/[^a-zA-Z0-9]/g, '').toLowerCase();\n\n const legacyMap: Record<string, ChannelState> = {\n NEGOTIATING_FUNDING: ChannelState.NegotiatingFunding,\n COLLABORATING_FUNDING_TX: ChannelState.CollaboratingFundingTx,\n SIGNING_COMMITMENT: ChannelState.SigningCommitment,\n AWAITING_TX_SIGNATURES: ChannelState.AwaitingTxSignatures,\n AWAITING_CHANNEL_READY: ChannelState.AwaitingChannelReady,\n CHANNEL_READY: ChannelState.ChannelReady,\n SHUTTING_DOWN: ChannelState.ShuttingDown,\n CLOSED: ChannelState.Closed,\n };\n\n if (legacy in legacyMap) return legacyMap[legacy];\n\n for (const value of Object.values(ChannelState)) {\n const normalizedValue = value.replace(/[^a-zA-Z0-9]/g, '').toLowerCase();\n if (normalizedValue === normalizedInput) return value;\n }\n\n return undefined;\n}\n\nexport function formatChannel(channel: Channel): Record<string, unknown> {\n const local = BigInt(channel.local_balance);\n const remote = BigInt(channel.remote_balance);\n const capacity = local + remote;\n const localPct = capacity > 0n ? Number((local * 100n) / capacity) : 0;\n const remotePct = capacity > 0n ? 100 - localPct : 0;\n\n return {\n channelId: channel.channel_id,\n channelIdShort: truncateMiddle(channel.channel_id, 10, 8),\n peerId: channel.peer_id,\n peerIdShort: truncateMiddle(channel.peer_id, 10, 8),\n state: channel.state.state_name,\n stateLabel: stateLabel(channel.state.state_name),\n stateFlags: channel.state.state_flags,\n localBalanceCkb: shannonsToCkb(channel.local_balance),\n remoteBalanceCkb: shannonsToCkb(channel.remote_balance),\n capacityCkb: shannonsToCkb(toHex(capacity)),\n balanceRatio: `${localPct}/${remotePct}`,\n pendingTlcs: channel.pending_tlcs.length,\n enabled: channel.enabled,\n isPublic: channel.is_public,\n age: formatAge(parseHexTimestampMs(channel.created_at)),\n };\n}\n\nexport function getChannelSummary(channels: Channel[]): Record<string, unknown> {\n let totalLocal = 0n;\n let totalRemote = 0n;\n let active = 0;\n\n for (const channel of channels) {\n totalLocal += BigInt(channel.local_balance);\n totalRemote += BigInt(channel.remote_balance || '0x0');\n if (channel.state.state_name === ChannelState.ChannelReady) {\n active++;\n }\n }\n\n return {\n count: channels.length,\n activeCount: active,\n totalLocalCkb: shannonsToCkb(toHex(totalLocal)),\n totalRemoteCkb: shannonsToCkb(toHex(totalRemote)),\n totalCapacityCkb: shannonsToCkb(toHex(totalLocal + totalRemote)),\n };\n}\n\nexport function extractInvoiceMetadata(invoice: CkbInvoice): {\n description?: string;\n expirySeconds?: number;\n expiresAt?: string;\n age: string;\n} {\n let description: string | undefined;\n let expirySeconds: number | undefined;\n\n for (const attr of invoice.data.attrs) {\n if ('Description' in attr) description = attr.Description;\n if ('ExpiryTime' in attr) {\n try {\n expirySeconds = Number(BigInt(attr.ExpiryTime));\n } catch {\n // ignore malformed expiry field\n }\n }\n }\n\n const createdMs = parseHexTimestampMs(invoice.data.timestamp);\n const expiresAt =\n createdMs && expirySeconds\n ? new Date(createdMs + expirySeconds * 1000).toISOString()\n : undefined;\n\n return {\n description,\n expirySeconds,\n expiresAt,\n age: formatAge(createdMs),\n };\n}\n\nexport function formatPaymentResult(payment: GetPaymentResult): Record<string, unknown> {\n const createdAtMs = parseHexTimestampMs(payment.created_at);\n const updatedAtMs = parseHexTimestampMs(payment.last_updated_at);\n\n return {\n paymentHash: payment.payment_hash,\n status: payment.status,\n feeCkb: shannonsToCkb(payment.fee),\n failureReason: payment.failed_error,\n createdAt: createdAtMs ? new Date(createdAtMs).toISOString() : payment.created_at,\n updatedAt: updatedAtMs ? new Date(updatedAtMs).toISOString() : payment.last_updated_at,\n routeCount: payment.routers?.length ?? 0,\n routers: payment.routers,\n };\n}\n\nexport function hasJsonFlag(args: string[]): boolean {\n return args.includes('--json');\n}\n\nexport function printJson(payload: unknown): void {\n console.log(JSON.stringify(payload, null, 2));\n}\n\nexport interface CliErrorPayload {\n code: string;\n message: string;\n recoverable?: boolean;\n suggestion?: string;\n details?: unknown;\n}\n\nexport function printJsonSuccess(data: unknown): void {\n printJson({ success: true, data });\n}\n\nexport function printJsonError(error: CliErrorPayload): void {\n printJson({ success: false, error });\n}\n\nexport function printJsonEvent(event: string, data: unknown, ts = new Date().toISOString()): void {\n process.stdout.write(`${JSON.stringify({ event, ts, data })}\\n`);\n}\n\nexport function printChannelDetailHuman(channel: Channel): void {\n const local = shannonsToCkb(channel.local_balance);\n const remote = shannonsToCkb(channel.remote_balance);\n const capacity = local + remote;\n\n console.log('Channel');\n console.log(` ID: ${channel.channel_id}`);\n console.log(` Peer: ${channel.peer_id}`);\n console.log(\n ` State: ${stateLabel(channel.state.state_name)} (${channel.state.state_name})`,\n );\n console.log(` Enabled: ${channel.enabled ? 'yes' : 'no'}`);\n console.log(` Public: ${channel.is_public ? 'yes' : 'no'}`);\n console.log(\n ` Balance: local ${local} CKB | remote ${remote} CKB | capacity ${capacity} CKB`,\n );\n console.log(` Pending TLCs: ${channel.pending_tlcs.length}`);\n console.log(` Age: ${formatAge(parseHexTimestampMs(channel.created_at))}`);\n console.log(\n ` Outpoint: ${channel.channel_outpoint ? `${channel.channel_outpoint.tx_hash}:${channel.channel_outpoint.index}` : 'n/a'}`,\n );\n console.log(` Commitment Tx: ${channel.latest_commitment_transaction_hash ?? 'n/a'}`);\n console.log(` Shutdown Tx: ${channel.shutdown_transaction_hash ?? 'n/a'}`);\n}\n\nexport function printInvoiceDetailHuman(data: {\n paymentHash: string;\n status: string;\n invoice: string;\n amountCkb?: number;\n currency: string;\n description?: string;\n createdAt: string;\n expiresAt?: string;\n age: string;\n}): void {\n console.log('Invoice');\n console.log(` Payment Hash: ${data.paymentHash}`);\n console.log(` Status: ${data.status}`);\n console.log(\n ` Amount: ${data.amountCkb ?? 'n/a'} ${data.amountCkb !== undefined ? 'CKB' : ''}`.trim(),\n );\n console.log(` Currency: ${data.currency}`);\n console.log(` Description: ${data.description ?? 'n/a'}`);\n console.log(` Created At: ${data.createdAt}`);\n console.log(` Expires At: ${data.expiresAt ?? 'n/a'}`);\n console.log(` Age: ${data.age}`);\n console.log(` Invoice: ${data.invoice}`);\n}\n\nexport function printPaymentDetailHuman(payment: GetPaymentResult): void {\n const createdAtMs = parseHexTimestampMs(payment.created_at);\n const updatedAtMs = parseHexTimestampMs(payment.last_updated_at);\n\n console.log('Payment');\n console.log(` Hash: ${payment.payment_hash}`);\n console.log(` Status: ${payment.status}`);\n console.log(` Fee: ${shannonsToCkb(payment.fee)} CKB`);\n console.log(` Failure: ${payment.failed_error ?? 'n/a'}`);\n console.log(\n ` Created At: ${createdAtMs ? new Date(createdAtMs).toISOString() : payment.created_at}`,\n );\n console.log(\n ` Updated At: ${updatedAtMs ? new Date(updatedAtMs).toISOString() : payment.last_updated_at}`,\n );\n const routers = payment.routers ?? [];\n console.log(` Routes: ${routers.length}`);\n if (routers.length > 0) {\n for (let i = 0; i < routers.length; i++) {\n const hops = routers[i].nodes.map((node) => truncateMiddle(node.pubkey, 8, 8)).join(' -> ');\n console.log(` #${i + 1}: ${hops}`);\n }\n }\n}\n\nexport function printChannelListHuman(channels: Channel[]): void {\n if (channels.length === 0) {\n console.log('No channels found.');\n return;\n }\n\n const summary = getChannelSummary(channels) as {\n count: number;\n activeCount: number;\n totalLocalCkb: number;\n totalRemoteCkb: number;\n totalCapacityCkb: number;\n };\n\n console.log(`Channels: ${summary.count} total, ${summary.activeCount} ready`);\n console.log(\n `Liquidity: local ${summary.totalLocalCkb} CKB | remote ${summary.totalRemoteCkb} CKB | capacity ${summary.totalCapacityCkb} CKB`,\n );\n console.log('');\n console.log(\n 'ID PEER STATE LOCAL REMOTE TLC',\n );\n console.log(\n '---------------------------------------------------------------------------------------------------',\n );\n\n for (const channel of channels) {\n const id = truncateMiddle(channel.channel_id, 10, 8).padEnd(22, ' ');\n const peer = truncateMiddle(channel.peer_id, 10, 8).padEnd(22, ' ');\n const state = channel.state.state_name.padEnd(24, ' ');\n const local = `${shannonsToCkb(channel.local_balance)}`.padStart(8, ' ');\n const remote = `${shannonsToCkb(channel.remote_balance)}`.padStart(8, ' ');\n const tlcs = `${channel.pending_tlcs.length}`.padStart(4, ' ');\n console.log(`${id} ${peer} ${state} ${local} ${remote} ${tlcs}`);\n }\n}\n\nexport function printBalanceHuman(data: {\n totalCkb: number;\n channelLocalCkb?: number;\n fundingAddress?: string;\n fundingAddressTotalCkb?: number;\n availableToSend: number;\n availableToReceive: number;\n channelCount: number;\n activeChannelCount: number;\n fundingBalanceError?: string;\n}): void {\n console.log('Balance');\n console.log(` Total: ${data.totalCkb} CKB`);\n if (data.channelLocalCkb !== undefined) {\n console.log(` In Channels (Local): ${data.channelLocalCkb} CKB`);\n }\n console.log(` Available To Send: ${data.availableToSend} CKB`);\n console.log(` Available To Receive: ${data.availableToReceive} CKB`);\n console.log(\n ` Channels: ${data.channelCount} total (${data.activeChannelCount} active)`,\n );\n if (data.fundingAddressTotalCkb !== undefined) {\n console.log(` Funding Address: ${data.fundingAddressTotalCkb} CKB`);\n }\n if (data.fundingAddress) {\n console.log(` Funding Lock Addr: ${data.fundingAddress}`);\n }\n if (data.fundingBalanceError) {\n console.log(` Funding Balance Note: ${data.fundingBalanceError}`);\n }\n}\n\nexport function printPeerListHuman(\n peers: Array<{ peer_id: string; pubkey: string; address: string }>,\n): void {\n if (peers.length === 0) {\n console.log('No connected peers.');\n return;\n }\n\n console.log(`Peers: ${peers.length}`);\n console.log('');\n console.log('PEER ID PUBKEY ADDRESS');\n console.log('--------------------------------------------------------------------------');\n for (const peer of peers) {\n const peerId = truncateMiddle(peer.peer_id, 10, 8).padEnd(22, ' ');\n const pubkey = truncateMiddle(peer.pubkey, 10, 8).padEnd(22, ' ');\n console.log(`${peerId} ${pubkey} ${peer.address}`);\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport { type ChannelState, ckbToShannons, type HexString } from '@fiber-pay/sdk';\nimport { Command } from 'commander';\nimport { sleep } from '../lib/async.js';\nimport type { CliConfig } from '../lib/config.js';\nimport {\n formatChannel,\n getChannelSummary,\n parseChannelState,\n printChannelDetailHuman,\n printChannelListHuman,\n printJsonError,\n printJsonEvent,\n printJsonSuccess,\n truncateMiddle,\n} from '../lib/format.js';\nimport { createReadyRpcClient, resolveRpcEndpoint } from '../lib/rpc.js';\nimport { tryCreateRuntimeChannelJob } from '../lib/runtime-jobs.js';\nimport { registerChannelRebalanceCommand } from './rebalance.js';\n\nexport function createChannelCommand(config: CliConfig): Command {\n const channel = new Command('channel').description('Channel lifecycle and status commands');\n\n channel\n .command('list')\n .option('--state <state>')\n .option('--peer <peerId>')\n .option('--include-closed')\n .option('--json')\n .action(async (options) => {\n const rpc = await createReadyRpcClient(config);\n const stateFilter = parseChannelState(options.state);\n const response = await rpc.listChannels(\n options.peer\n ? { peer_id: options.peer, include_closed: Boolean(options.includeClosed) }\n : { include_closed: Boolean(options.includeClosed) },\n );\n const channels = stateFilter\n ? response.channels.filter((item) => item.state.state_name === stateFilter)\n : response.channels;\n\n if (options.json) {\n printJsonSuccess({ channels, count: channels.length });\n } else {\n printChannelListHuman(channels);\n }\n });\n\n channel\n .command('get')\n .argument('<channelId>')\n .option('--json')\n .action(async (channelId, options) => {\n const rpc = await createReadyRpcClient(config);\n const response = await rpc.listChannels({ include_closed: true });\n const found = response.channels.find((item) => item.channel_id === channelId);\n if (!found) {\n if (options.json) {\n printJsonError({\n code: 'CHANNEL_NOT_FOUND',\n message: `Channel not found: ${channelId}`,\n recoverable: true,\n suggestion: 'List channels first and retry with a valid channel id.',\n details: { channelId },\n });\n } else {\n console.error(`Error: Channel not found: ${channelId}`);\n }\n process.exit(1);\n }\n\n if (options.json) {\n printJsonSuccess(found);\n } else {\n printChannelDetailHuman(found);\n }\n });\n\n channel\n .command('watch')\n .option('--interval <seconds>', 'Refresh interval', '5')\n .option('--timeout <seconds>')\n .option('--on-timeout <behavior>', 'fail | success', 'fail')\n .option('--channel <channelId>')\n .option('--peer <peerId>')\n .option('--state <state>')\n .option('--until <state>')\n .option('--include-closed')\n .option('--no-clear')\n .option('--json')\n .action(async (options) => {\n const intervalSeconds = parseInt(options.interval, 10);\n const timeoutSeconds = options.timeout ? parseInt(options.timeout, 10) : undefined;\n const onTimeout = String(options.onTimeout ?? 'fail')\n .trim()\n .toLowerCase();\n const stateFilter = parseChannelState(options.state);\n const untilState = parseChannelState(options.until);\n const noClear = Boolean(options.noClear);\n const json = Boolean(options.json);\n if (!['fail', 'success'].includes(onTimeout)) {\n if (json) {\n printJsonError({\n code: 'CHANNEL_WATCH_INPUT_INVALID',\n message: `Invalid --on-timeout value: ${options.onTimeout}. Expected fail or success`,\n recoverable: true,\n suggestion: 'Use `--on-timeout fail` or `--on-timeout success`.',\n details: { provided: options.onTimeout, expected: ['fail', 'success'] },\n });\n } else {\n console.error(\n `Error: Invalid --on-timeout value: ${options.onTimeout}. Expected fail or success`,\n );\n }\n process.exit(1);\n }\n const rpc = await createReadyRpcClient(config);\n const startedAt = Date.now();\n const previousStates = new Map<string, ChannelState>();\n\n while (true) {\n const response = await rpc.listChannels(\n options.peer\n ? { peer_id: options.peer, include_closed: Boolean(options.includeClosed) }\n : { include_closed: Boolean(options.includeClosed) },\n );\n let channels = response.channels;\n\n if (options.channel) {\n channels = channels.filter((item) => item.channel_id === options.channel);\n }\n if (stateFilter) {\n channels = channels.filter((item) => item.state.state_name === stateFilter);\n }\n\n const stateChanges: Array<{ channelId: string; from: ChannelState; to: ChannelState }> = [];\n for (const ch of channels) {\n const prev = previousStates.get(ch.channel_id);\n if (prev && prev !== ch.state.state_name) {\n stateChanges.push({ channelId: ch.channel_id, from: prev, to: ch.state.state_name });\n }\n previousStates.set(ch.channel_id, ch.state.state_name);\n }\n\n if (json) {\n printJsonEvent('snapshot', {\n channels: channels.map(formatChannel),\n summary: getChannelSummary(channels),\n });\n\n for (const change of stateChanges) {\n printJsonEvent('state_change', {\n channelId: change.channelId,\n from: change.from,\n to: change.to,\n });\n }\n } else {\n if (!noClear) {\n console.clear();\n }\n\n console.log(`⏱️ Channel monitor - ${new Date().toISOString()}`);\n console.log(\n ` Refresh: ${intervalSeconds}s${timeoutSeconds ? ` | Timeout: ${timeoutSeconds}s` : ''}${untilState ? ` | Until: ${untilState}` : ''}`,\n );\n\n if (stateChanges.length > 0) {\n console.log('\\n🔔 State changes:');\n for (const change of stateChanges) {\n console.log(` ${truncateMiddle(change.channelId)}: ${change.from} -> ${change.to}`);\n }\n }\n\n printChannelListHuman(channels);\n }\n\n if (untilState && channels.some((item) => item.state.state_name === untilState)) {\n if (json) {\n printJsonEvent('terminal', { reason: 'target_state_reached', untilState });\n } else {\n console.log(`\\n✅ Target state reached: ${untilState}`);\n }\n return;\n }\n\n if (timeoutSeconds !== undefined && Date.now() - startedAt >= timeoutSeconds * 1000) {\n if (onTimeout === 'success') {\n if (json) {\n printJsonEvent('terminal', {\n reason: 'timeout',\n timeoutSeconds,\n });\n } else {\n console.log('\\n⏰ Monitor timeout reached (treated as success).');\n }\n return;\n }\n\n if (json) {\n printJsonError({\n code: 'CHANNEL_WATCH_TIMEOUT',\n message: `Channel monitor timed out after ${timeoutSeconds}s`,\n recoverable: true,\n suggestion: 'Increase timeout or continue monitoring with another watch run.',\n details: { timeoutSeconds },\n });\n process.exit(1);\n }\n console.log('\\n⏰ Monitor timeout reached.');\n return;\n }\n\n await sleep(intervalSeconds * 1000);\n }\n });\n\n channel\n .command('open')\n .requiredOption('--peer <peerIdOrMultiaddr>')\n .requiredOption('--funding <ckb>')\n .option('--private')\n .option(\n '--idempotency-key <key>',\n 'Reuse this key only when retrying the exact same open intent',\n )\n .option('--json')\n .action(async (options) => {\n const rpc = await createReadyRpcClient(config);\n const json = Boolean(options.json);\n const peerInput = options.peer as string;\n const fundingCkb = parseFloat(options.funding);\n\n let peerId = peerInput;\n if (peerInput.includes('/')) {\n await rpc.connectPeer({ address: peerInput });\n const peerIdMatch = peerInput.match(/\\/p2p\\/([^/]+)/);\n if (peerIdMatch) peerId = peerIdMatch[1];\n }\n\n const idempotencyKey =\n typeof options.idempotencyKey === 'string' && options.idempotencyKey.trim().length > 0\n ? options.idempotencyKey.trim()\n : `open:${peerId}:${randomUUID()}`;\n\n const endpoint = resolveRpcEndpoint(config);\n if (endpoint.target === 'runtime-proxy') {\n const created = await tryCreateRuntimeChannelJob(endpoint.url, {\n params: {\n action: 'open',\n peerId,\n openChannelParams: {\n peer_id: peerId,\n funding_amount: ckbToShannons(fundingCkb),\n public: !options.private,\n },\n waitForReady: false,\n },\n options: {\n idempotencyKey,\n reuseTerminal: false,\n },\n });\n\n if (created) {\n const payload = {\n jobId: created.id,\n jobState: created.state,\n peer: peerId,\n fundingCkb,\n idempotencyKey,\n };\n\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log('Channel open job submitted');\n console.log(` Job: ${payload.jobId}`);\n console.log(` Job State: ${payload.jobState}`);\n console.log(` Peer: ${payload.peer}`);\n console.log(` Funding: ${payload.fundingCkb} CKB`);\n console.log(` Idempotency Key: ${payload.idempotencyKey}`);\n }\n return;\n }\n }\n\n const result = await rpc.openChannel({\n peer_id: peerId,\n funding_amount: ckbToShannons(fundingCkb),\n public: !options.private,\n });\n\n const payload = { temporaryChannelId: result.temporary_channel_id, peer: peerId, fundingCkb };\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log('Channel open initiated');\n console.log(` Temporary Channel ID: ${payload.temporaryChannelId}`);\n console.log(` Peer: ${payload.peer}`);\n console.log(` Funding: ${payload.fundingCkb} CKB`);\n }\n });\n\n channel\n .command('accept')\n .argument('<temporaryChannelId>')\n .requiredOption('--funding <ckb>')\n .option('--json')\n .action(async (temporaryChannelId, options) => {\n const rpc = await createReadyRpcClient(config);\n const json = Boolean(options.json);\n const fundingCkb = parseFloat(options.funding);\n\n const endpoint = resolveRpcEndpoint(config);\n if (endpoint.target === 'runtime-proxy') {\n const created = await tryCreateRuntimeChannelJob(endpoint.url, {\n params: {\n action: 'accept',\n acceptChannelParams: {\n temporary_channel_id: temporaryChannelId as HexString,\n funding_amount: ckbToShannons(fundingCkb),\n },\n },\n options: {\n idempotencyKey: `accept:temporary:${temporaryChannelId}`,\n },\n });\n\n if (created) {\n const payload = {\n jobId: created.id,\n jobState: created.state,\n temporaryChannelId,\n fundingCkb,\n };\n\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log('Channel accept job submitted');\n console.log(` Job: ${payload.jobId}`);\n console.log(` Job State: ${payload.jobState}`);\n console.log(` Temporary Channel ID: ${payload.temporaryChannelId}`);\n console.log(` Funding: ${payload.fundingCkb} CKB`);\n }\n return;\n }\n }\n\n const result = await rpc.acceptChannel({\n temporary_channel_id: temporaryChannelId as HexString,\n funding_amount: ckbToShannons(fundingCkb),\n });\n\n const payload = { channelId: result.channel_id, temporaryChannelId, fundingCkb };\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log('Channel accepted');\n console.log(` Channel ID: ${payload.channelId}`);\n console.log(` Temporary Channel ID: ${payload.temporaryChannelId}`);\n console.log(` Funding: ${payload.fundingCkb} CKB`);\n }\n });\n\n channel\n .command('close')\n .argument('<channelId>')\n .option('--force')\n .option('--json')\n .action(async (channelId, options) => {\n const rpc = await createReadyRpcClient(config);\n const json = Boolean(options.json);\n\n const endpoint = resolveRpcEndpoint(config);\n if (endpoint.target === 'runtime-proxy') {\n const created = await tryCreateRuntimeChannelJob(endpoint.url, {\n params: {\n action: 'shutdown',\n channelId: channelId as HexString,\n shutdownChannelParams: {\n channel_id: channelId as HexString,\n force: Boolean(options.force),\n },\n waitForClosed: Boolean(options.force),\n },\n options: {\n idempotencyKey: `shutdown:channel:${channelId}`,\n },\n });\n\n if (created) {\n const payload = {\n jobId: created.id,\n jobState: created.state,\n channelId,\n force: Boolean(options.force),\n message: options.force\n ? 'Channel force close job submitted'\n : 'Channel close job submitted',\n };\n\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log(payload.message);\n console.log(` Job: ${payload.jobId}`);\n console.log(` Job State: ${payload.jobState}`);\n console.log(` Channel ID: ${payload.channelId}`);\n }\n return;\n }\n }\n\n await rpc.shutdownChannel({\n channel_id: channelId as HexString,\n force: Boolean(options.force),\n });\n const payload = {\n channelId,\n force: Boolean(options.force),\n message: options.force ? 'Channel force close initiated' : 'Channel close initiated',\n };\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log(payload.message);\n console.log(` Channel ID: ${payload.channelId}`);\n }\n });\n\n channel\n .command('abandon')\n .argument('<channelId>')\n .option('--json')\n .action(async (channelId, options) => {\n const rpc = await createReadyRpcClient(config);\n const json = Boolean(options.json);\n\n const endpoint = resolveRpcEndpoint(config);\n if (endpoint.target === 'runtime-proxy') {\n const created = await tryCreateRuntimeChannelJob(endpoint.url, {\n params: {\n action: 'abandon',\n channelId: channelId as HexString,\n abandonChannelParams: {\n channel_id: channelId as HexString,\n },\n },\n options: {\n idempotencyKey: `abandon:channel:${channelId}`,\n },\n });\n\n if (created) {\n const payload = {\n jobId: created.id,\n jobState: created.state,\n channelId,\n message: 'Channel abandon job submitted.',\n };\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log(payload.message);\n console.log(` Job: ${payload.jobId}`);\n console.log(` Job State: ${payload.jobState}`);\n console.log(` Channel ID: ${payload.channelId}`);\n }\n return;\n }\n }\n\n await rpc.abandonChannel({ channel_id: channelId as HexString });\n const payload = { channelId, message: 'Channel abandoned.' };\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log(payload.message);\n console.log(` Channel ID: ${payload.channelId}`);\n }\n });\n\n registerChannelRebalanceCommand(channel, config);\n\n channel\n .command('update')\n .argument('<channelId>')\n .option('--enabled <enabled>')\n .option('--tlc-expiry-delta <ms>')\n .option('--tlc-minimum-value <shannonsHex>')\n .option('--tlc-fee-proportional-millionths <value>')\n .option('--json')\n .action(async (channelId, options) => {\n const rpc = await createReadyRpcClient(config);\n const json = Boolean(options.json);\n const updateParams = {\n channel_id: channelId as HexString,\n enabled: options.enabled !== undefined ? options.enabled === 'true' : undefined,\n tlc_expiry_delta: options.tlcExpiryDelta,\n tlc_minimum_value: options.tlcMinimumValue,\n tlc_fee_proportional_millionths: options.tlcFeeProportionalMillionths,\n };\n\n const endpoint = resolveRpcEndpoint(config);\n if (endpoint.target === 'runtime-proxy') {\n const created = await tryCreateRuntimeChannelJob(endpoint.url, {\n params: {\n action: 'update',\n channelId: channelId as HexString,\n updateChannelParams: updateParams,\n },\n options: {\n reuseTerminal: false,\n },\n });\n\n if (created) {\n const payload = {\n jobId: created.id,\n jobState: created.state,\n channelId,\n message: 'Channel update job submitted.',\n };\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log(payload.message);\n console.log(` Job: ${payload.jobId}`);\n console.log(` Job State: ${payload.jobState}`);\n console.log(` Channel ID: ${payload.channelId}`);\n }\n return;\n }\n }\n\n await rpc.updateChannel(updateParams);\n const payload = { channelId, message: 'Channel updated.' };\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log(payload.message);\n console.log(` Channel ID: ${payload.channelId}`);\n }\n });\n\n return channel;\n}\n","export function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import { FiberRpcClient } from '@fiber-pay/sdk';\nimport type { CliConfig } from './config.js';\nimport { isProcessRunning } from './pid.js';\nimport { readRuntimeMeta, readRuntimePid } from './runtime-meta.js';\n\nexport type ResolvedRpcTarget = 'node-rpc' | 'runtime-proxy';\n\nexport interface ResolvedRpcEndpoint {\n url: string;\n target: ResolvedRpcTarget;\n}\n\nfunction normalizeUrl(url: string): string {\n try {\n const normalized = new URL(url).toString();\n return normalized.endsWith('/') ? normalized.slice(0, -1) : normalized;\n } catch {\n return url.endsWith('/') ? url.slice(0, -1) : url;\n }\n}\n\nfunction resolveRuntimeProxyUrl(config: CliConfig): string | undefined {\n const runtimeMeta = readRuntimeMeta(config.dataDir);\n const runtimePid = readRuntimePid(config.dataDir);\n\n if (!runtimeMeta || !runtimePid || !isProcessRunning(runtimePid)) {\n return undefined;\n }\n\n if (!runtimeMeta.proxyListen || !runtimeMeta.fiberRpcUrl) {\n return undefined;\n }\n\n if (normalizeUrl(runtimeMeta.fiberRpcUrl) !== normalizeUrl(config.rpcUrl)) {\n return undefined;\n }\n\n if (\n runtimeMeta.proxyListen.startsWith('http://') ||\n runtimeMeta.proxyListen.startsWith('https://')\n ) {\n return runtimeMeta.proxyListen;\n }\n\n return `http://${runtimeMeta.proxyListen}`;\n}\n\nexport function createRpcClient(config: CliConfig): FiberRpcClient {\n const resolved = resolveRpcEndpoint(config);\n return new FiberRpcClient({\n url: resolved.url,\n biscuitToken: config.rpcBiscuitToken,\n });\n}\n\nexport function resolveRpcEndpoint(config: CliConfig): ResolvedRpcEndpoint {\n const runtimeProxyUrl = resolveRuntimeProxyUrl(config);\n if (runtimeProxyUrl) {\n return {\n url: runtimeProxyUrl,\n target: 'runtime-proxy',\n };\n }\n\n return {\n url: config.rpcUrl,\n target: 'node-rpc',\n };\n}\n\nexport async function createReadyRpcClient(\n config: CliConfig,\n options: { timeout?: number; interval?: number } = {},\n): Promise<FiberRpcClient> {\n const rpc = createRpcClient(config);\n await rpc.waitForReady({ timeout: options.timeout ?? 3000, interval: options.interval ?? 500 });\n return rpc;\n}\n","import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\nexport function getPidFilePath(dataDir: string): string {\n return join(dataDir, 'fiber.pid');\n}\n\nexport function writePidFile(dataDir: string, pid: number): void {\n writeFileSync(getPidFilePath(dataDir), String(pid));\n}\n\nexport function readPidFile(dataDir: string): number | null {\n const pidPath = getPidFilePath(dataDir);\n if (!existsSync(pidPath)) return null;\n\n try {\n return parseInt(readFileSync(pidPath, 'utf-8').trim(), 10);\n } catch {\n return null;\n }\n}\n\nexport function removePidFile(dataDir: string): void {\n const pidPath = getPidFilePath(dataDir);\n if (existsSync(pidPath)) {\n unlinkSync(pidPath);\n }\n}\n\nexport function isProcessRunning(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n","import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\nexport interface RuntimeMeta {\n pid: number;\n startedAt: string;\n fiberRpcUrl: string;\n proxyListen: string;\n stateFilePath?: string;\n alertLogFilePath?: string;\n fnnStdoutLogPath?: string;\n fnnStderrLogPath?: string;\n /** Base logs directory for discovering daily log directories. */\n logsBaseDir?: string;\n daemon: boolean;\n}\n\nexport function getRuntimePidFilePath(dataDir: string): string {\n return join(dataDir, 'runtime.pid');\n}\n\nexport function getRuntimeMetaFilePath(dataDir: string): string {\n return join(dataDir, 'runtime.meta.json');\n}\n\nexport function writeRuntimePid(dataDir: string, pid: number): void {\n writeFileSync(getRuntimePidFilePath(dataDir), String(pid));\n}\n\nexport function readRuntimePid(dataDir: string): number | null {\n const pidPath = getRuntimePidFilePath(dataDir);\n if (!existsSync(pidPath)) return null;\n try {\n return Number.parseInt(readFileSync(pidPath, 'utf-8').trim(), 10);\n } catch {\n return null;\n }\n}\n\nexport function writeRuntimeMeta(dataDir: string, meta: RuntimeMeta): void {\n writeFileSync(getRuntimeMetaFilePath(dataDir), JSON.stringify(meta, null, 2));\n}\n\nexport function readRuntimeMeta(dataDir: string): RuntimeMeta | null {\n const metaPath = getRuntimeMetaFilePath(dataDir);\n if (!existsSync(metaPath)) return null;\n try {\n return JSON.parse(readFileSync(metaPath, 'utf-8')) as RuntimeMeta;\n } catch {\n return null;\n }\n}\n\nexport function removeRuntimeFiles(dataDir: string): void {\n const pidPath = getRuntimePidFilePath(dataDir);\n const metaPath = getRuntimeMetaFilePath(dataDir);\n if (existsSync(pidPath)) {\n unlinkSync(pidPath);\n }\n if (existsSync(metaPath)) {\n unlinkSync(metaPath);\n }\n}\n","import { sleep } from './async.js';\n\nexport type RuntimeJobRecord = {\n id: string;\n type?: string;\n state: string;\n params?: Record<string, unknown>;\n idempotencyKey?: string;\n retryCount?: number;\n maxRetries?: number;\n createdAt?: number;\n updatedAt?: number;\n completedAt?: number;\n result?:\n | {\n paymentHash?: string;\n fee?: string;\n failedError?: string;\n }\n | Record<string, unknown>;\n error?: { message?: string };\n};\n\nexport type RuntimeJobEventRecord = {\n id: string;\n eventType: string;\n fromState?: string;\n toState?: string;\n createdAt: number;\n data?: unknown;\n};\n\nexport type RuntimePaymentJobRequest = {\n params: {\n invoice?: string;\n sendPaymentParams: Record<string, unknown>;\n };\n options?: {\n idempotencyKey?: string;\n maxRetries?: number;\n };\n};\n\nexport type RuntimeChannelJobRequest = {\n params: {\n action: 'open' | 'shutdown' | 'accept' | 'abandon' | 'update';\n openChannelParams?: Record<string, unknown>;\n shutdownChannelParams?: Record<string, unknown>;\n acceptChannelParams?: Record<string, unknown>;\n abandonChannelParams?: Record<string, unknown>;\n updateChannelParams?: Record<string, unknown>;\n peerId?: string;\n channelId?: string;\n waitForReady?: boolean;\n waitForClosed?: boolean;\n pollIntervalMs?: number;\n };\n options?: {\n idempotencyKey?: string;\n maxRetries?: number;\n reuseTerminal?: boolean;\n };\n};\n\nexport type RuntimeInvoiceJobRequest = {\n params: {\n action: 'create' | 'watch' | 'cancel' | 'settle';\n newInvoiceParams?: Record<string, unknown>;\n getInvoicePaymentHash?: string;\n cancelInvoiceParams?: Record<string, unknown>;\n settleInvoiceParams?: Record<string, unknown>;\n waitForTerminal?: boolean;\n pollIntervalMs?: number;\n };\n options?: {\n idempotencyKey?: string;\n maxRetries?: number;\n };\n};\n\nexport async function tryCreateRuntimePaymentJob(\n runtimeUrl: string,\n body: RuntimePaymentJobRequest,\n): Promise<RuntimeJobRecord | null> {\n try {\n const response = await fetch(`${runtimeUrl}/jobs/payment`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(body),\n });\n if (!response.ok) return null;\n return (await response.json()) as RuntimeJobRecord;\n } catch {\n return null;\n }\n}\n\nexport async function tryCreateRuntimeChannelJob(\n runtimeUrl: string,\n body: RuntimeChannelJobRequest,\n): Promise<RuntimeJobRecord | null> {\n try {\n const response = await fetch(`${runtimeUrl}/jobs/channel`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(body),\n });\n if (!response.ok) return null;\n return (await response.json()) as RuntimeJobRecord;\n } catch {\n return null;\n }\n}\n\nexport async function tryCreateRuntimeInvoiceJob(\n runtimeUrl: string,\n body: RuntimeInvoiceJobRequest,\n): Promise<RuntimeJobRecord | null> {\n try {\n const response = await fetch(`${runtimeUrl}/jobs/invoice`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(body),\n });\n if (!response.ok) return null;\n return (await response.json()) as RuntimeJobRecord;\n } catch {\n return null;\n }\n}\n\nexport async function waitForRuntimeJobTerminal(\n runtimeUrl: string,\n jobId: string,\n timeoutSeconds: number,\n): Promise<RuntimeJobRecord> {\n const startedAt = Date.now();\n while (Date.now() - startedAt < timeoutSeconds * 1000) {\n const response = await fetch(`${runtimeUrl}/jobs/${jobId}`);\n if (!response.ok) {\n throw new Error(`Failed to fetch runtime job ${jobId}: ${response.status}`);\n }\n const job = (await response.json()) as RuntimeJobRecord;\n if (job.state === 'succeeded' || job.state === 'failed' || job.state === 'cancelled') {\n return job;\n }\n await sleep(500);\n }\n throw new Error(`Timed out waiting for runtime job ${jobId}`);\n}\n","import { ckbToShannons, type HexString, shannonsToCkb } from '@fiber-pay/sdk';\nimport type { Command } from 'commander';\nimport type { CliConfig } from '../lib/config.js';\nimport { printJsonError, printJsonSuccess } from '../lib/format.js';\nimport { createReadyRpcClient } from '../lib/rpc.js';\n\ninterface RebalanceExecutionParams {\n amountInput: string;\n maxFeeInput?: string;\n hops?: string[];\n dryRun: boolean;\n json: boolean;\n errorCode: 'PAYMENT_REBALANCE_INPUT_INVALID' | 'CHANNEL_REBALANCE_INPUT_INVALID';\n}\n\nasync function executeRebalance(\n config: CliConfig,\n params: RebalanceExecutionParams,\n): Promise<void> {\n const rpc = await createReadyRpcClient(config);\n const amountCkb = parseFloat(params.amountInput);\n const maxFeeCkb = params.maxFeeInput !== undefined ? parseFloat(params.maxFeeInput) : undefined;\n const manualHops = params.hops ?? [];\n\n if (!Number.isFinite(amountCkb) || amountCkb <= 0) {\n const message = 'Invalid --amount value. Expected a positive CKB amount.';\n if (params.json) {\n printJsonError({\n code: params.errorCode,\n message,\n recoverable: true,\n suggestion: 'Provide a positive number, e.g. `--amount 10`.',\n details: { amount: params.amountInput },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n\n if (\n maxFeeCkb !== undefined &&\n (!Number.isFinite(maxFeeCkb) || maxFeeCkb < 0 || manualHops.length > 0)\n ) {\n const message =\n manualHops.length > 0\n ? '--max-fee is only supported in auto rebalance mode (without manual hops).'\n : 'Invalid --max-fee value. Expected a non-negative CKB amount.';\n if (params.json) {\n printJsonError({\n code: params.errorCode,\n message,\n recoverable: true,\n suggestion:\n manualHops.length > 0\n ? 'Remove `--max-fee` or run auto mode without manual hops.'\n : 'Provide a non-negative number, e.g. `--max-fee 0.01`.',\n details: { maxFee: params.maxFeeInput, hasManualHops: manualHops.length > 0 },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n\n const selfPubkey = (await rpc.nodeInfo()).node_id as HexString;\n const amount = ckbToShannons(amountCkb);\n const isManual = manualHops.length > 0;\n let routeHopCount: number | undefined;\n\n const result = isManual\n ? await (async () => {\n const hopsInfo = [\n ...manualHops.map((pubkey: string) => ({ pubkey: pubkey as HexString })),\n ...(manualHops[manualHops.length - 1] === selfPubkey\n ? []\n : [{ pubkey: selfPubkey as HexString }]),\n ];\n\n const route = await rpc.buildRouter({\n amount,\n hops_info: hopsInfo,\n });\n routeHopCount = route.router_hops.length;\n\n return rpc.sendPaymentWithRouter({\n router: route.router_hops,\n keysend: true,\n allow_self_payment: true,\n dry_run: params.dryRun ? true : undefined,\n });\n })()\n : await rpc.sendPayment({\n target_pubkey: selfPubkey,\n amount,\n keysend: true,\n allow_self_payment: true,\n max_fee_amount: maxFeeCkb !== undefined ? ckbToShannons(maxFeeCkb) : undefined,\n dry_run: params.dryRun ? true : undefined,\n });\n\n const payload = {\n mode: isManual ? 'manual' : 'auto',\n selfPubkey,\n amountCkb,\n maxFeeCkb: isManual ? undefined : maxFeeCkb,\n routeHopCount,\n paymentHash: result.payment_hash,\n status:\n result.status === 'Success' ? 'success' : result.status === 'Failed' ? 'failed' : 'pending',\n feeCkb: shannonsToCkb(result.fee),\n failureReason: result.failed_error,\n dryRun: params.dryRun,\n };\n\n if (params.json) {\n printJsonSuccess(payload);\n } else {\n console.log(\n payload.dryRun\n ? `Rebalance dry-run complete (${payload.mode} route)`\n : `Rebalance sent (${payload.mode} route)`,\n );\n console.log(` Self: ${payload.selfPubkey}`);\n console.log(` Amount: ${payload.amountCkb} CKB`);\n if (payload.mode === 'manual' && payload.routeHopCount !== undefined) {\n console.log(` Hops: ${payload.routeHopCount}`);\n }\n console.log(` Hash: ${payload.paymentHash}`);\n console.log(` Status: ${payload.status}`);\n console.log(` Fee: ${payload.feeCkb} CKB`);\n if (payload.mode === 'auto' && payload.maxFeeCkb !== undefined) {\n console.log(` MaxFee: ${payload.maxFeeCkb} CKB`);\n }\n if (payload.failureReason) {\n console.log(` Error: ${payload.failureReason}`);\n }\n }\n}\n\nexport function registerPaymentRebalanceCommand(parent: Command, config: CliConfig): void {\n parent\n .command('rebalance')\n .description('Technical rebalance command mapped to payment-layer circular self-payment')\n .requiredOption('--amount <ckb>', 'Amount in CKB to rebalance')\n .option('--max-fee <ckb>', 'Maximum fee in CKB (auto mode only)')\n .option(\n '--hops <pubkeys>',\n 'Comma-separated peer pubkeys for manual route mode (self pubkey appended automatically)',\n )\n .option('--dry-run', 'Simulate route/payment and return estimated result')\n .option('--json')\n .action(async (options) => {\n const hasHopsOption = typeof options.hops === 'string';\n const manualHops = hasHopsOption\n ? options.hops\n .split(',')\n .map((item: string) => item.trim())\n .filter(Boolean)\n : [];\n\n if (hasHopsOption && manualHops.length === 0) {\n const message =\n 'Invalid --hops value. Expected a non-empty comma-separated list of pubkeys.';\n if (options.json) {\n printJsonError({\n code: 'PAYMENT_REBALANCE_INPUT_INVALID',\n message,\n recoverable: true,\n suggestion: 'Provide pubkeys like `--hops 0xabc...,0xdef...`.',\n details: { hops: options.hops },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n\n await executeRebalance(config, {\n amountInput: options.amount,\n maxFeeInput: options.maxFee,\n hops: manualHops,\n dryRun: Boolean(options.dryRun),\n json: Boolean(options.json),\n errorCode: 'PAYMENT_REBALANCE_INPUT_INVALID',\n });\n });\n}\n\nexport function registerChannelRebalanceCommand(parent: Command, config: CliConfig): void {\n parent\n .command('rebalance')\n .description('High-level channel rebalance wrapper using payment-layer orchestration')\n .requiredOption('--amount <ckb>', 'Amount in CKB to rebalance')\n .option('--from-channel <channelId>', 'Source-biased channel id (optional)')\n .option('--to-channel <channelId>', 'Destination-biased channel id (optional)')\n .option('--max-fee <ckb>', 'Maximum fee in CKB (auto mode only)')\n .option('--dry-run', 'Simulate route/payment and return estimated result')\n .option('--json')\n .action(async (options) => {\n const json = Boolean(options.json);\n const fromChannelId = options.fromChannel as string | undefined;\n const toChannelId = options.toChannel as string | undefined;\n\n if ((fromChannelId && !toChannelId) || (!fromChannelId && toChannelId)) {\n const message =\n 'Both --from-channel and --to-channel must be provided together for guided channel rebalance.';\n if (json) {\n printJsonError({\n code: 'CHANNEL_REBALANCE_INPUT_INVALID',\n message,\n recoverable: true,\n suggestion: 'Provide both channel ids, or provide neither to run auto mode.',\n details: { fromChannel: fromChannelId, toChannel: toChannelId },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n\n let guidedHops: string[] | undefined;\n if (fromChannelId && toChannelId) {\n const rpc = await createReadyRpcClient(config);\n const channels = (await rpc.listChannels({ include_closed: true })).channels;\n const fromChannel = channels.find((item) => item.channel_id === fromChannelId);\n const toChannel = channels.find((item) => item.channel_id === toChannelId);\n\n if (!fromChannel || !toChannel) {\n const message = 'Invalid channel selection: source/target channel id not found.';\n if (json) {\n printJsonError({\n code: 'CHANNEL_REBALANCE_INPUT_INVALID',\n message,\n recoverable: true,\n suggestion: 'Run `channel list --json` and retry with valid channel ids.',\n details: { fromChannel: fromChannelId, toChannel: toChannelId },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n\n if (fromChannel.peer_id === toChannel.peer_id) {\n const message =\n 'Source and target channels point to the same peer; choose two different channel peers.';\n if (json) {\n printJsonError({\n code: 'CHANNEL_REBALANCE_INPUT_INVALID',\n message,\n recoverable: true,\n suggestion: 'Select channels with different peer ids for guided rebalance.',\n details: {\n fromChannel: fromChannelId,\n toChannel: toChannelId,\n peerId: fromChannel.peer_id,\n },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n\n const peers = (await rpc.listPeers()).peers;\n const pubkeyByPeerId = new Map(peers.map((peer) => [peer.peer_id, peer.pubkey]));\n const fromPubkey = pubkeyByPeerId.get(fromChannel.peer_id);\n const toPubkey = pubkeyByPeerId.get(toChannel.peer_id);\n\n if (!fromPubkey || !toPubkey) {\n const message =\n 'Unable to resolve selected channel peer_id to pubkey for guided rebalance route.';\n if (json) {\n printJsonError({\n code: 'CHANNEL_REBALANCE_INPUT_INVALID',\n message,\n recoverable: true,\n suggestion:\n 'Ensure both peers are connected (`peer list --json`) and retry guided mode, or use `payment rebalance --hops`.',\n details: {\n fromChannel: fromChannelId,\n toChannel: toChannelId,\n fromPeerId: fromChannel.peer_id,\n toPeerId: toChannel.peer_id,\n resolvedPeers: peers.length,\n },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n\n guidedHops = [fromPubkey, toPubkey];\n }\n\n await executeRebalance(config, {\n amountInput: options.amount,\n maxFeeInput: options.maxFee,\n hops: guidedHops,\n dryRun: Boolean(options.dryRun),\n json,\n errorCode: 'CHANNEL_REBALANCE_INPUT_INVALID',\n });\n });\n}\n","import { existsSync, readFileSync, writeFileSync } from 'node:fs';\nimport { Command } from 'commander';\nimport { parseDocument, stringify as yamlStringify } from 'yaml';\nimport {\n type CliConfig,\n getEffectiveConfig,\n loadProfileConfig,\n type ProfileConfig,\n parseNetworkFromConfig,\n saveProfileConfig,\n writeNetworkConfigFile,\n} from '../lib/config.js';\nimport type { FiberNetwork } from '../lib/config-templates.js';\nimport { printJsonError, printJsonSuccess } from '../lib/format.js';\n\nfunction parseNetworkInput(input: string | undefined): FiberNetwork {\n if (!input) return 'testnet';\n if (input === 'testnet' || input === 'mainnet') return input;\n throw new Error(`Invalid network: ${input}. Expected one of: testnet, mainnet`);\n}\n\nfunction parsePortInput(\n input: string | undefined,\n label: 'rpc-port' | 'p2p-port' | 'proxy-port',\n): number | undefined {\n if (input === undefined) return undefined;\n const parsed = Number.parseInt(input, 10);\n if (!Number.isInteger(parsed) || parsed < 1 || parsed > 65535) {\n throw new Error(`Invalid ${label}: ${input}. Expected integer in range 1-65535.`);\n }\n return parsed;\n}\n\nfunction resolvePort(\n optionValue: string | undefined,\n envValue: string | undefined,\n label: 'rpc-port' | 'p2p-port',\n): { value: number | undefined; source: 'option' | 'env' | 'unset' } {\n if (optionValue !== undefined) {\n return { value: parsePortInput(optionValue, label), source: 'option' };\n }\n if (envValue !== undefined) {\n return { value: parsePortInput(envValue, label), source: 'env' };\n }\n return { value: undefined, source: 'unset' };\n}\n\ntype ConfigValueType = 'auto' | 'string' | 'number' | 'boolean' | 'null' | 'json';\ntype ConfigPathSegment = string | number;\n\nconst LEGACY_PATH_ALIASES: Record<string, string> = {\n chain: 'fiber.chain',\n};\n\nfunction resolveConfigPathAlias(path: string): string {\n return LEGACY_PATH_ALIASES[path] ?? path;\n}\n\nfunction parseConfigPath(path: string): ConfigPathSegment[] {\n const normalized = resolveConfigPathAlias(path).trim();\n if (!normalized) {\n throw new Error('Config path cannot be empty.');\n }\n\n const segments: ConfigPathSegment[] = [];\n const re = /([^.[\\]]+)|\\[(\\d+)\\]/g;\n for (const match of normalized.matchAll(re)) {\n if (match[1]) {\n segments.push(match[1]);\n } else if (match[2]) {\n segments.push(Number.parseInt(match[2], 10));\n }\n }\n\n if (segments.length === 0) {\n throw new Error(`Invalid config path: ${path}`);\n }\n\n return segments;\n}\n\nfunction parseTypedValue(raw: string, valueType: ConfigValueType): unknown {\n if (valueType === 'string') return raw;\n if (valueType === 'null') return null;\n\n if (valueType === 'number') {\n const parsed = Number(raw);\n if (!Number.isFinite(parsed)) {\n throw new Error(`Invalid number value: ${raw}`);\n }\n return parsed;\n }\n\n if (valueType === 'boolean') {\n const lowered = raw.toLowerCase();\n if (lowered === 'true') return true;\n if (lowered === 'false') return false;\n throw new Error(`Invalid boolean value: ${raw}. Expected true or false.`);\n }\n\n if (valueType === 'json') {\n try {\n return JSON.parse(raw);\n } catch {\n throw new Error(`Invalid JSON value: ${raw}`);\n }\n }\n\n const lowered = raw.toLowerCase();\n if (lowered === 'true') return true;\n if (lowered === 'false') return false;\n if (lowered === 'null') return null;\n\n if (/^-?\\d+(\\.\\d+)?$/.test(raw)) {\n return Number(raw);\n }\n\n if ((raw.startsWith('{') && raw.endsWith('}')) || (raw.startsWith('[') && raw.endsWith(']'))) {\n try {\n return JSON.parse(raw);\n } catch {\n return raw;\n }\n }\n\n return raw;\n}\n\nfunction ensureConfigFileOrExit(configPath: string, json: boolean): void {\n if (!existsSync(configPath)) {\n const msg = `Config file not found: ${configPath}. Run \\`fiber-pay config init\\` first.`;\n if (json) {\n printJsonError({\n code: 'CONFIG_NOT_FOUND',\n message: msg,\n recoverable: true,\n suggestion: 'Run `fiber-pay config init --network testnet` and retry.',\n });\n } else {\n console.error(`Error: ${msg}`);\n }\n process.exit(1);\n }\n}\n\nfunction normalizeHexScalarsForMutation(content: string): string {\n return content.replace(\n /^(\\s*)(code_hash|tx_hash|args):\\s*(0x[0-9a-fA-F]+)(\\s*(#.*))?$/gm,\n (_match, indent: string, key: string, value: string, tail = '') =>\n `${indent}${key}: \"${value}\"${tail}`,\n );\n}\n\nfunction parseConfigDocumentForMutation(configPath: string) {\n const raw = readFileSync(configPath, 'utf-8');\n const normalized = normalizeHexScalarsForMutation(raw);\n return parseDocument(normalized, {\n keepSourceTokens: true,\n });\n}\n\nfunction collectConfigPaths(value: unknown, prefix = ''): string[] {\n if (value === null || value === undefined) {\n return prefix ? [prefix] : [];\n }\n\n if (Array.isArray(value)) {\n if (value.length === 0) {\n return prefix ? [prefix] : [];\n }\n const result: string[] = [];\n for (let index = 0; index < value.length; index++) {\n const childPrefix = `${prefix}[${index}]`;\n result.push(...collectConfigPaths(value[index], childPrefix));\n }\n return result;\n }\n\n if (typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>);\n if (entries.length === 0) {\n return prefix ? [prefix] : [];\n }\n const result: string[] = [];\n for (const [key, child] of entries) {\n const childPrefix = prefix ? `${prefix}.${key}` : key;\n result.push(...collectConfigPaths(child, childPrefix));\n }\n return result;\n }\n\n return prefix ? [prefix] : [];\n}\n\nexport function createConfigCommand(_config: CliConfig): Command {\n const config = new Command('config').description('Single source configuration management');\n\n config\n .command('init')\n .option(\n '--data-dir <path>',\n 'Target data directory (overrides FIBER_DATA_DIR for this command)',\n )\n .option('--network <network>', 'testnet | mainnet')\n .option('--rpc-port <port>', 'Override rpc.listening_addr port in generated config')\n .option('--p2p-port <port>', 'Override fiber.listening_addr port in generated config')\n .option('--proxy-port <port>', 'Set runtime proxy port and persist in profile.json')\n .option('--force', 'Overwrite existing config file')\n .option('--json')\n .action(async (options) => {\n const effective = getEffectiveConfig();\n const dataDir = options.dataDir ?? effective.config.dataDir;\n const selectedNetwork = options.network\n ? parseNetworkInput(options.network)\n : effective.config.network;\n const rpcPort = resolvePort(options.rpcPort, process.env.FIBER_RPC_PORT, 'rpc-port');\n const p2pPort = resolvePort(options.p2pPort, process.env.FIBER_P2P_PORT, 'p2p-port');\n const result = writeNetworkConfigFile(dataDir, selectedNetwork, {\n force: Boolean(options.force),\n rpcPort: rpcPort.value,\n p2pPort: p2pPort.value,\n });\n\n // Persist proxy port into profile.json if specified\n let proxyPort: number | undefined;\n if (options.proxyPort !== undefined) {\n proxyPort = parsePortInput(options.proxyPort, 'proxy-port');\n const existing = loadProfileConfig(dataDir) ?? {};\n existing.runtimeProxyListen = `127.0.0.1:${proxyPort}`;\n saveProfileConfig(dataDir, existing);\n }\n\n const payload = {\n configPath: result.path,\n dataDir,\n network: selectedNetwork,\n rpcPort: rpcPort.value,\n rpcPortSource: rpcPort.source,\n p2pPort: p2pPort.value,\n p2pPortSource: p2pPort.source,\n proxyPort: proxyPort ?? null,\n created: result.created,\n overwritten: result.overwritten,\n skipped: !result.created && !result.overwritten,\n };\n\n if (options.json) {\n printJsonSuccess(payload);\n } else {\n if (result.created) {\n console.log(`✅ Config initialized: ${result.path}`);\n } else if (result.overwritten) {\n console.log(`✅ Config overwritten: ${result.path}`);\n } else {\n console.log(`ℹ️ Config already exists: ${result.path}`);\n console.log(' Use --force to overwrite.');\n }\n if (options.dataDir !== undefined) {\n console.log(` Data Dir: ${dataDir} (option)`);\n } else {\n console.log(` Data Dir: ${dataDir} (${effective.sources.dataDir})`);\n }\n console.log(` Network: ${selectedNetwork}`);\n if (rpcPort.value !== undefined)\n console.log(` RPC Port: ${rpcPort.value} (${rpcPort.source})`);\n if (p2pPort.value !== undefined)\n console.log(` P2P Port: ${p2pPort.value} (${p2pPort.source})`);\n if (proxyPort !== undefined) console.log(` Proxy Port: ${proxyPort} (profile.json)`);\n }\n });\n\n config\n .command('show')\n .option('--effective', 'Debug resolved values and value source')\n .option('--json')\n .action(async (options) => {\n const effective = getEffectiveConfig();\n\n if (options.effective) {\n const payload = {\n config: effective.config,\n sources: effective.sources,\n configExists: effective.configExists,\n };\n\n if (options.json) {\n printJsonSuccess(payload);\n } else {\n console.log('Effective Config');\n console.log(` Data Dir: ${effective.config.dataDir} (${effective.sources.dataDir})`);\n console.log(` Config Path: ${effective.config.configPath}`);\n console.log(` Network: ${effective.config.network} (${effective.sources.network})`);\n console.log(` RPC URL: ${effective.config.rpcUrl} (${effective.sources.rpcUrl})`);\n console.log(` Exists: ${effective.configExists ? 'yes' : 'no'}`);\n }\n return;\n }\n\n if (!effective.configExists) {\n if (options.json) {\n printJsonError({\n code: 'CONFIG_NOT_FOUND',\n message: `Config file not found: ${effective.config.configPath}`,\n recoverable: true,\n suggestion: 'Run `fiber-pay config init --network testnet` and retry.',\n details: { configPath: effective.config.configPath },\n });\n } else {\n console.error(`Error: Config file not found: ${effective.config.configPath}`);\n console.error('Run: fiber-pay config init --network testnet');\n }\n process.exit(1);\n }\n\n const content = readFileSync(effective.config.configPath, 'utf-8');\n const fileNetwork = parseNetworkFromConfig(content) || 'unknown';\n\n if (options.json) {\n printJsonSuccess({\n path: effective.config.configPath,\n network: fileNetwork,\n content,\n });\n } else {\n console.log(`# ${effective.config.configPath} (${fileNetwork})`);\n console.log(content);\n }\n });\n\n config\n .command('get')\n .description('Get config value by path (e.g. fiber.chain, ckb.udt_whitelist[0].name)')\n .argument('<path>', 'Config path')\n .option('--json')\n .action(async (path, options) => {\n const effective = getEffectiveConfig();\n const json = Boolean(options.json);\n const configPath = effective.config.configPath;\n ensureConfigFileOrExit(configPath, json);\n\n const doc = parseConfigDocumentForMutation(configPath);\n const segments = parseConfigPath(path);\n const value = doc.getIn(segments as (string | number)[]);\n\n if (value === undefined) {\n const msg = `Config path not found: ${resolveConfigPathAlias(path)}`;\n if (json) {\n printJsonError({\n code: 'CONFIG_PATH_NOT_FOUND',\n message: msg,\n recoverable: true,\n suggestion: 'Use `fiber-pay config list` to inspect available paths.',\n });\n } else {\n console.error(`Error: ${msg}`);\n }\n process.exit(1);\n }\n\n if (json) {\n printJsonSuccess({ path: resolveConfigPathAlias(path), value });\n } else if (typeof value === 'object') {\n console.log(yamlStringify(value).trimEnd());\n } else {\n console.log(String(value));\n }\n });\n\n config\n .command('set')\n .description('Set config value by path (supports nested keys and array indexes)')\n .argument('<path>', 'Config path')\n .argument('<value>', 'New value')\n .option('--type <type>', 'auto|string|number|boolean|null|json', 'auto')\n .option('--json')\n .action(async (path, value, options) => {\n const effective = getEffectiveConfig();\n const json = Boolean(options.json);\n const configPath = effective.config.configPath;\n ensureConfigFileOrExit(configPath, json);\n\n const valueType = String(options.type ?? 'auto') as ConfigValueType;\n if (!['auto', 'string', 'number', 'boolean', 'null', 'json'].includes(valueType)) {\n const msg = `Invalid --type: ${options.type}. Expected auto|string|number|boolean|null|json`;\n if (json) {\n printJsonError({\n code: 'CONFIG_VALUE_TYPE_INVALID',\n message: msg,\n recoverable: true,\n });\n } else {\n console.error(`Error: ${msg}`);\n }\n process.exit(1);\n }\n\n const doc = parseConfigDocumentForMutation(configPath);\n const resolvedPath = resolveConfigPathAlias(path);\n const segments = parseConfigPath(path);\n const parsedValue = parseTypedValue(value, valueType);\n\n doc.setIn(segments as (string | number)[], parsedValue);\n writeFileSync(configPath, doc.toString({ lineWidth: 0 }), 'utf-8');\n\n if (json) {\n printJsonSuccess({ path: resolvedPath, value: parsedValue, configPath });\n } else {\n console.log(`✅ Set ${resolvedPath} = ${value} in ${configPath}`);\n }\n });\n\n config\n .command('unset')\n .description('Remove config value by path')\n .argument('<path>', 'Config path')\n .option('--json')\n .action(async (path, options) => {\n const effective = getEffectiveConfig();\n const json = Boolean(options.json);\n const configPath = effective.config.configPath;\n ensureConfigFileOrExit(configPath, json);\n\n const doc = parseConfigDocumentForMutation(configPath);\n const resolvedPath = resolveConfigPathAlias(path);\n const segments = parseConfigPath(path);\n const removed = doc.deleteIn(segments as (string | number)[]);\n\n if (!removed) {\n const msg = `Config path not found: ${resolvedPath}`;\n if (json) {\n printJsonError({\n code: 'CONFIG_PATH_NOT_FOUND',\n message: msg,\n recoverable: true,\n suggestion: 'Use `fiber-pay config list` to inspect available paths.',\n });\n } else {\n console.error(`Error: ${msg}`);\n }\n process.exit(1);\n }\n\n writeFileSync(configPath, doc.toString({ lineWidth: 0 }), 'utf-8');\n\n if (json) {\n printJsonSuccess({ path: resolvedPath, removed: true, configPath });\n } else {\n console.log(`✅ Removed ${resolvedPath} from ${configPath}`);\n }\n });\n\n config\n .command('list')\n .description('List config key paths (optionally under a prefix)')\n .option('--prefix <path>', 'List only under this path')\n .option('--json')\n .action(async (options) => {\n const effective = getEffectiveConfig();\n const json = Boolean(options.json);\n const configPath = effective.config.configPath;\n ensureConfigFileOrExit(configPath, json);\n\n const doc = parseConfigDocumentForMutation(configPath);\n const prefix = options.prefix ? resolveConfigPathAlias(String(options.prefix)) : undefined;\n\n let rootValue: unknown = doc.toJSON();\n let basePrefix = '';\n\n if (prefix) {\n const segments = parseConfigPath(prefix);\n rootValue = doc.getIn(segments as (string | number)[]);\n if (rootValue === undefined) {\n const msg = `Config path not found: ${prefix}`;\n if (json) {\n printJsonError({\n code: 'CONFIG_PATH_NOT_FOUND',\n message: msg,\n recoverable: true,\n suggestion: 'Use `fiber-pay config list` without prefix first.',\n });\n } else {\n console.error(`Error: ${msg}`);\n }\n process.exit(1);\n }\n basePrefix = prefix;\n }\n\n const paths = collectConfigPaths(rootValue, basePrefix).sort((a, b) => a.localeCompare(b));\n\n if (json) {\n printJsonSuccess({ prefix: prefix ?? null, paths, count: paths.length });\n } else {\n for (const path of paths) {\n console.log(path);\n }\n }\n });\n\n // ---------------------------------------------------------------------------\n // config profile — manage profile.json key-value settings\n // ---------------------------------------------------------------------------\n const profile = new Command('profile').description(\n 'Manage profile.json settings (CLI-only overrides)',\n );\n\n const PROFILE_KEYS: (keyof ProfileConfig)[] = ['binaryPath', 'keyPassword', 'runtimeProxyListen'];\n\n profile\n .command('show')\n .description('Show current profile.json values')\n .option('--json')\n .action(async (options) => {\n const effective = getEffectiveConfig();\n const profileData = loadProfileConfig(effective.config.dataDir);\n\n if (options.json) {\n printJsonSuccess({ dataDir: effective.config.dataDir, profile: profileData ?? {} });\n } else {\n if (!profileData || Object.keys(profileData).length === 0) {\n console.log('No profile settings found.');\n console.log(` Location: ${effective.config.dataDir}/profile.json`);\n return;\n }\n console.log('Profile Settings');\n console.log(` Location: ${effective.config.dataDir}/profile.json`);\n for (const key of PROFILE_KEYS) {\n if (profileData[key] !== undefined) {\n console.log(` ${key}: ${profileData[key]}`);\n }\n }\n }\n });\n\n profile\n .command('set')\n .description('Set a profile key')\n .argument('<key>', `One of: ${PROFILE_KEYS.join(', ')}`)\n .argument('<value>')\n .option('--json')\n .action(async (key, value, options) => {\n if (!PROFILE_KEYS.includes(key as keyof ProfileConfig)) {\n const msg = `Unknown profile key: ${key}. Valid keys: ${PROFILE_KEYS.join(', ')}`;\n if (options.json) {\n printJsonError({\n code: 'PROFILE_INVALID_KEY',\n message: msg,\n recoverable: true,\n suggestion: `Use one of: ${PROFILE_KEYS.join(', ')}`,\n });\n } else {\n console.error(`Error: ${msg}`);\n }\n process.exit(1);\n }\n\n const effective = getEffectiveConfig();\n const existing = loadProfileConfig(effective.config.dataDir) ?? {};\n\n (existing as Record<string, unknown>)[key] = value;\n saveProfileConfig(effective.config.dataDir, existing);\n\n if (options.json) {\n printJsonSuccess({ key, value, dataDir: effective.config.dataDir });\n } else {\n console.log(`✅ Profile key \"${key}\" set to \"${value}\"`);\n }\n });\n\n profile\n .command('unset')\n .description('Remove a profile key')\n .argument('<key>', `One of: ${PROFILE_KEYS.join(', ')}`)\n .option('--json')\n .action(async (key, options) => {\n if (!PROFILE_KEYS.includes(key as keyof ProfileConfig)) {\n const msg = `Unknown profile key: ${key}. Valid keys: ${PROFILE_KEYS.join(', ')}`;\n if (options.json) {\n printJsonError({\n code: 'PROFILE_INVALID_KEY',\n message: msg,\n recoverable: true,\n suggestion: `Use one of: ${PROFILE_KEYS.join(', ')}`,\n });\n } else {\n console.error(`Error: ${msg}`);\n }\n process.exit(1);\n }\n\n const effective = getEffectiveConfig();\n const existing = loadProfileConfig(effective.config.dataDir) ?? {};\n delete (existing as Record<string, unknown>)[key];\n saveProfileConfig(effective.config.dataDir, existing);\n\n if (options.json) {\n printJsonSuccess({ key, removed: true, dataDir: effective.config.dataDir });\n } else {\n console.log(`✅ Profile key \"${key}\" removed`);\n }\n });\n\n config.addCommand(profile);\n\n return config;\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { type FiberNetwork, getConfigTemplate } from './config-templates.js';\n\nexport interface CliConfig {\n binaryPath?: string;\n dataDir: string;\n configPath: string;\n network: FiberNetwork;\n rpcUrl: string;\n rpcBiscuitToken?: string;\n keyPassword?: string;\n ckbRpcUrl?: string;\n runtimeProxyListen?: string;\n}\n\n/** Keys that can be stored in a profile.json file. */\nexport interface ProfileConfig {\n binaryPath?: string;\n keyPassword?: string;\n runtimeProxyListen?: string;\n}\n\nexport interface EffectiveConfigSources {\n dataDir: 'cli' | 'env' | 'default';\n configPath: 'derived';\n network: 'cli' | 'env' | 'config' | 'default';\n rpcUrl: 'cli' | 'env' | 'config' | 'default';\n rpcBiscuitToken?: 'cli' | 'env' | 'unset';\n ckbRpcUrl?: 'env' | 'config' | 'unset';\n runtimeProxyListen?: 'cli' | 'env' | 'profile' | 'default';\n}\n\nexport interface EffectiveConfig {\n config: CliConfig;\n sources: EffectiveConfigSources;\n configExists: boolean;\n}\n\nconst DEFAULT_DATA_DIR = `${process.env.HOME}/.fiber-pay`;\nconst DEFAULT_RPC_URL = 'http://127.0.0.1:8227';\nconst DEFAULT_NETWORK: FiberNetwork = 'testnet';\n\nexport function getConfigPath(dataDir: string): string {\n return join(dataDir, 'config.yml');\n}\n\nexport function parseNetworkFromConfig(configContent: string): FiberNetwork | undefined {\n const match = configContent.match(/^\\s*chain:\\s*(testnet|mainnet)\\s*$/m);\n if (!match) return undefined;\n return match[1] as FiberNetwork;\n}\n\nexport function parseRpcUrlFromConfig(configContent: string): string | undefined {\n const rpcSectionMatch = configContent.match(\n /(^|\\n)rpc:\\n([\\s\\S]*?)(\\n[a-zA-Z_]+:|\\nservices:|$)/,\n );\n const rpcSection = rpcSectionMatch?.[2];\n if (!rpcSection) return undefined;\n\n const match = rpcSection.match(/^\\s*listening_addr:\\s*\"?([^\"\\n]+)\"?\\s*$/m);\n if (!match) return undefined;\n const listeningAddr = match[1].trim();\n if (!listeningAddr) return undefined;\n if (listeningAddr.startsWith('http://') || listeningAddr.startsWith('https://')) {\n return listeningAddr;\n }\n return `http://${listeningAddr}`;\n}\n\nexport function parseCkbRpcUrlFromConfig(configContent: string): string | undefined {\n const ckbSectionMatch = configContent.match(\n /(^|\\n)ckb:\\n([\\s\\S]*?)(\\n[a-zA-Z_]+:|\\nservices:|$)/,\n );\n const ckbSection = ckbSectionMatch?.[2];\n if (!ckbSection) return undefined;\n\n const match = ckbSection.match(/^\\s*rpc_url:\\s*\"?([^\"\\n]+)\"?\\s*$/m);\n return match?.[1]?.trim() || undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Profile helpers\n// ---------------------------------------------------------------------------\n\nfunction getProfilePath(dataDir: string): string {\n return join(dataDir, 'profile.json');\n}\n\nexport function loadProfileConfig(dataDir: string): ProfileConfig | undefined {\n const profilePath = getProfilePath(dataDir);\n if (!existsSync(profilePath)) return undefined;\n try {\n const raw = readFileSync(profilePath, 'utf-8');\n return JSON.parse(raw) as ProfileConfig;\n } catch {\n return undefined;\n }\n}\n\nexport function saveProfileConfig(dataDir: string, profile: ProfileConfig): void {\n if (!existsSync(dataDir)) {\n mkdirSync(dataDir, { recursive: true });\n }\n const profilePath = getProfilePath(dataDir);\n writeFileSync(profilePath, `${JSON.stringify(profile, null, 2)}\\n`, 'utf-8');\n}\n\nexport function writeNetworkConfigFile(\n dataDir: string,\n network: FiberNetwork,\n options: { force?: boolean; rpcPort?: number; p2pPort?: number } = {},\n): { path: string; created: boolean; overwritten: boolean } {\n const configPath = getConfigPath(dataDir);\n const alreadyExists = existsSync(configPath);\n\n if (alreadyExists && !options.force) {\n return { path: configPath, created: false, overwritten: false };\n }\n\n if (!existsSync(dataDir)) {\n mkdirSync(dataDir, { recursive: true });\n }\n\n let content = getConfigTemplate(network);\n\n if (options.rpcPort !== undefined || options.p2pPort !== undefined) {\n const lines = content.split('\\n');\n let section: string | null = null;\n\n for (let i = 0; i < lines.length; i++) {\n const sectionMatch = lines[i].match(/^([a-zA-Z_]+):\\s*$/);\n if (sectionMatch) {\n section = sectionMatch[1];\n continue;\n }\n\n if (\n section === 'fiber' &&\n options.p2pPort !== undefined &&\n /^\\s*listening_addr:\\s*/.test(lines[i])\n ) {\n lines[i] = ` listening_addr: \"/ip4/127.0.0.1/tcp/${options.p2pPort}\"`;\n } else if (\n section === 'rpc' &&\n options.rpcPort !== undefined &&\n /^\\s*listening_addr:\\s*/.test(lines[i])\n ) {\n lines[i] = ` listening_addr: \"127.0.0.1:${options.rpcPort}\"`;\n }\n }\n\n content = lines.join('\\n');\n }\n\n writeFileSync(configPath, content, 'utf-8');\n return { path: configPath, created: !alreadyExists, overwritten: alreadyExists };\n}\n\nexport function ensureNodeConfigFile(dataDir: string, network: FiberNetwork): string {\n const configPath = getConfigPath(dataDir);\n if (!existsSync(configPath)) {\n writeNetworkConfigFile(dataDir, network);\n }\n return configPath;\n}\n\nexport function getEffectiveConfig(explicitFlags?: Set<string>): EffectiveConfig {\n const dataDir = process.env.FIBER_DATA_DIR || DEFAULT_DATA_DIR;\n const dataDirSource: EffectiveConfigSources['dataDir'] = explicitFlags?.has('dataDir')\n ? 'cli'\n : process.env.FIBER_DATA_DIR\n ? 'env'\n : 'default';\n\n const configPath = getConfigPath(dataDir);\n const configExists = existsSync(configPath);\n const configContent = configExists ? readFileSync(configPath, 'utf-8') : undefined;\n\n // Load profile.json from the resolved data directory\n const profile = loadProfileConfig(dataDir);\n\n // --- Per-key priority ---\n // runtime keys: CLI flag > env var > config.yml > default\n // CLI-only keys: CLI flag > profile.json > env var\n\n // Network\n const cliNetwork = explicitFlags?.has('network')\n ? (process.env.FIBER_NETWORK as FiberNetwork | undefined)\n : undefined;\n const envNetwork = !explicitFlags?.has('network')\n ? (process.env.FIBER_NETWORK as FiberNetwork | undefined)\n : undefined;\n const fileNetwork = configContent ? parseNetworkFromConfig(configContent) : undefined;\n const network = cliNetwork || envNetwork || fileNetwork || DEFAULT_NETWORK;\n const networkSource: EffectiveConfigSources['network'] = cliNetwork\n ? 'cli'\n : envNetwork\n ? 'env'\n : fileNetwork\n ? 'config'\n : 'default';\n\n // RPC URL\n const cliRpcUrl = explicitFlags?.has('rpcUrl') ? process.env.FIBER_RPC_URL : undefined;\n const envRpcUrl = !explicitFlags?.has('rpcUrl') ? process.env.FIBER_RPC_URL : undefined;\n const fileRpcUrl = configContent ? parseRpcUrlFromConfig(configContent) : undefined;\n const rpcUrl = cliRpcUrl || envRpcUrl || fileRpcUrl || DEFAULT_RPC_URL;\n const rpcUrlSource: EffectiveConfigSources['rpcUrl'] = cliRpcUrl\n ? 'cli'\n : envRpcUrl\n ? 'env'\n : fileRpcUrl\n ? 'config'\n : 'default';\n\n // RPC Biscuit token (auth bearer token)\n const cliRpcBiscuitToken = explicitFlags?.has('rpcBiscuitToken')\n ? process.env.FIBER_RPC_BISCUIT_TOKEN\n : undefined;\n const envRpcBiscuitToken = !explicitFlags?.has('rpcBiscuitToken')\n ? process.env.FIBER_RPC_BISCUIT_TOKEN\n : undefined;\n const rpcBiscuitToken = cliRpcBiscuitToken || envRpcBiscuitToken || undefined;\n const rpcBiscuitTokenSource: EffectiveConfigSources['rpcBiscuitToken'] = cliRpcBiscuitToken\n ? 'cli'\n : envRpcBiscuitToken\n ? 'env'\n : 'unset';\n\n // Binary path\n const cliBinaryPath = explicitFlags?.has('binaryPath')\n ? process.env.FIBER_BINARY_PATH\n : undefined;\n const profileBinaryPath = profile?.binaryPath;\n const envBinaryPath = !explicitFlags?.has('binaryPath')\n ? process.env.FIBER_BINARY_PATH\n : undefined;\n const binaryPath = cliBinaryPath || profileBinaryPath || envBinaryPath || undefined;\n\n // Key password\n const cliKeyPassword = explicitFlags?.has('keyPassword')\n ? process.env.FIBER_KEY_PASSWORD\n : undefined;\n const profileKeyPassword = profile?.keyPassword;\n const envKeyPassword = !explicitFlags?.has('keyPassword')\n ? process.env.FIBER_KEY_PASSWORD\n : undefined;\n const keyPassword = cliKeyPassword || profileKeyPassword || envKeyPassword || undefined;\n\n // CKB RPC URL\n const envCkbRpcUrl = process.env.FIBER_CKB_RPC_URL;\n const fileCkbRpcUrl = configContent ? parseCkbRpcUrlFromConfig(configContent) : undefined;\n const ckbRpcUrl = envCkbRpcUrl || fileCkbRpcUrl || undefined;\n const ckbRpcUrlSource: EffectiveConfigSources['ckbRpcUrl'] = envCkbRpcUrl\n ? 'env'\n : fileCkbRpcUrl\n ? 'config'\n : 'unset';\n\n // Runtime proxy listen — CLI flag > env var > profile.json > default\n const DEFAULT_RUNTIME_PROXY_LISTEN = '127.0.0.1:8229';\n const cliRuntimeProxyListen = explicitFlags?.has('runtimeProxyListen')\n ? process.env.FIBER_RUNTIME_PROXY_LISTEN\n : undefined;\n const envRuntimeProxyListen = !explicitFlags?.has('runtimeProxyListen')\n ? process.env.FIBER_RUNTIME_PROXY_LISTEN\n : undefined;\n const profileRuntimeProxyListen = profile?.runtimeProxyListen;\n const runtimeProxyListen =\n cliRuntimeProxyListen ||\n envRuntimeProxyListen ||\n profileRuntimeProxyListen ||\n DEFAULT_RUNTIME_PROXY_LISTEN;\n const runtimeProxyListenSource: EffectiveConfigSources['runtimeProxyListen'] =\n cliRuntimeProxyListen\n ? 'cli'\n : envRuntimeProxyListen\n ? 'env'\n : profileRuntimeProxyListen\n ? 'profile'\n : 'default';\n\n return {\n configExists,\n config: {\n binaryPath,\n dataDir,\n configPath,\n network,\n rpcUrl,\n rpcBiscuitToken,\n keyPassword,\n ckbRpcUrl,\n runtimeProxyListen,\n },\n sources: {\n dataDir: dataDirSource,\n configPath: 'derived',\n network: networkSource,\n rpcUrl: rpcUrlSource,\n rpcBiscuitToken: rpcBiscuitTokenSource,\n ckbRpcUrl: ckbRpcUrlSource,\n runtimeProxyListen: runtimeProxyListenSource,\n },\n };\n}\n\nexport function getConfig(): CliConfig {\n return getEffectiveConfig().config;\n}\n","export type FiberNetwork = 'testnet' | 'mainnet';\n\nexport const TESTNET_CONFIG_TEMPLATE_V071 = `# This configuration file only contains the necessary configurations for the testnet deployment.\n# All options' descriptions can be found via \\`fnn --help\\` and be overridden by command line arguments or environment variables.\nfiber:\n listening_addr: \"/ip4/0.0.0.0/tcp/8228\"\n bootnode_addrs:\n - \"/ip4/54.179.226.154/tcp/8228/p2p/Qmes1EBD4yNo9Ywkfe6eRw9tG1nVNGLDmMud1xJMsoYFKy\"\n - \"/ip4/16.163.7.105/tcp/8228/p2p/QmdyQWjPtbK4NWWsvy8s69NGJaQULwgeQDT5ZpNDrTNaeV\"\n announce_listening_addr: true\n announced_addrs:\n # If you want to announce your fiber node public address to the network, you need to add the address here, please change the ip to your public ip accordingly.\n # - \"/ip4/YOUR-FIBER-NODE-PUBLIC-IP/tcp/8228\"\n chain: testnet\n # lock script configurations related to fiber network\n # https://github.com/nervosnetwork/fiber-scripts/blob/main/deployment/testnet/migrations/2025-02-28-111246.json\n scripts:\n - name: FundingLock\n script:\n code_hash: \"0x6c67887fe201ee0c7853f1682c0b77c0e6214044c156c7558269390a8afa6d7c\"\n hash_type: type\n args: \"0x\"\n cell_deps:\n - type_id:\n code_hash: \"0x00000000000000000000000000000000000000000000000000545950455f4944\"\n hash_type: type\n args: \"0x3cb7c0304fe53f75bb5727e2484d0beae4bd99d979813c6fc97c3cca569f10f6\"\n - cell_dep:\n out_point:\n tx_hash: \"0x12c569a258dd9c5bd99f632bb8314b1263b90921ba31496467580d6b79dd14a7\" # ckb_auth\n index: 0x0\n dep_type: code\n - name: CommitmentLock\n script:\n code_hash: \"0x740dee83f87c6f309824d8fd3fbdd3c8380ee6fc9acc90b1a748438afcdf81d8\"\n hash_type: type\n args: \"0x\"\n cell_deps:\n - type_id:\n code_hash: \"0x00000000000000000000000000000000000000000000000000545950455f4944\"\n hash_type: type\n args: \"0xf7e458887495cf70dd30d1543cad47dc1dfe9d874177bf19291e4db478d5751b\"\n - cell_dep:\n out_point:\n tx_hash: \"0x12c569a258dd9c5bd99f632bb8314b1263b90921ba31496467580d6b79dd14a7\" #ckb_auth\n index: 0x0\n dep_type: code\n\nrpc:\n # By default RPC only binds to localhost, thus it only allows accessing from the same machine.\n # Allowing arbitrary machines to access the JSON-RPC port is dangerous and strongly discouraged.\n # Please strictly limit the access to only trusted machines.\n listening_addr: \"127.0.0.1:8227\"\n\nckb:\n rpc_url: \"https://testnet.ckbapp.dev/\"\n udt_whitelist:\n - name: RUSD\n script:\n code_hash: \"0x1142755a044bf2ee358cba9f2da187ce928c91cd4dc8692ded0337efa677d21a\"\n hash_type: type\n args: \"0x878fcc6f1f08d48e87bb1c3b3d5083f23f8a39c5d5c764f253b55b998526439b\"\n cell_deps:\n - type_id:\n code_hash: \"0x00000000000000000000000000000000000000000000000000545950455f4944\"\n hash_type: type\n args: \"0x97d30b723c0b2c66e9cb8d4d0df4ab5d7222cbb00d4a9a2055ce2e5d7f0d8b0f\"\n auto_accept_amount: 1000000000\n\nservices:\n - fiber\n - rpc\n - ckb\n`;\n\nexport const MAINNET_CONFIG_TEMPLATE_V071 = `# This configuration file only contains the necessary configurations for the mainnet deployment.\n# All options' descriptions can be found via \\`fnn --help\\` and be overridden by command line arguments or environment variables.\nfiber:\n listening_addr: \"/ip4/0.0.0.0/tcp/8228\"\n bootnode_addrs:\n - \"/ip4/43.199.24.44/tcp/8228/p2p/QmZ2gCTfEF6vKsiYFF2STPeA2rRLRim9nMtzfwiE7uMQ4v\"\n - \"/ip4/54.255.71.126/tcp/8228/p2p/QmcMLnWraRyxd7PFRgvn1QeYRQS2DGsP6fPFCQjtfMs5b2\"\n announce_listening_addr: true\n announced_addrs:\n # If you want to announce your fiber node public address to the network, you need to add the address here.\n # Please change the ip to your public ip accordingly, and make sure the port is open and reachable from the internet.\n # - \"/ip4/YOUR-FIBER-NODE-PUBLIC-IP/tcp/8228\"\n chain: mainnet\n # lock script configurations related to fiber network\n # https://github.com/nervosnetwork/fiber-scripts/blob/main/deployment/mainnet/migrations/2025-02-28-114908.json\n scripts:\n - name: FundingLock\n script:\n code_hash: \"0xe45b1f8f21bff23137035a3ab751d75b36a981deec3e7820194b9c042967f4f1\"\n hash_type: type\n args: \"0x\"\n cell_deps:\n - type_id:\n code_hash: \"0x00000000000000000000000000000000000000000000000000545950455f4944\"\n hash_type: type\n args: \"0x64818d82a372312fb007c480391e1b9759d21b2c7f7959b9c177d72cdc243394\"\n - cell_dep:\n out_point:\n tx_hash: \"0x95006eee7b4c0c8ad66e0514c88ed0ae43fc8db27793427de86a348ec720b9d6\" # ckb_auth\n index: 0x0\n dep_type: code\n - name: CommitmentLock\n script:\n code_hash: \"0x2d45c4d3ed3e942f1945386ee82a5d1b7e4bb16d7fe1ab015421174ab747406c\"\n hash_type: type\n args: \"0x\"\n cell_deps:\n - type_id:\n code_hash: \"0x00000000000000000000000000000000000000000000000000545950455f4944\"\n hash_type: type\n args: \"0xdb16e6dcb17f670e5fb7c556d81e522ec5edb069ad2fa3e898e7ccea6c26a39f\"\n - cell_dep:\n out_point:\n tx_hash: \"0x95006eee7b4c0c8ad66e0514c88ed0ae43fc8db27793427de86a348ec720b9d6\" #ckb_auth\n index: 0x0\n dep_type: code\n\nrpc:\n # By default RPC only binds to localhost, thus it only allows accessing from the same machine.\n # Allowing arbitrary machines to access the JSON-RPC port is dangerous and strongly discouraged.\n # Please strictly limit the access to only trusted machines.\n listening_addr: \"127.0.0.1:8227\"\n\nckb:\n # Please use a trusted CKB RPC node, the node should be able to provide the correct data and should be stable.\n rpc_url: \"http://127.0.0.1:8114/\"\n udt_whitelist:\n ## https://github.com/CKBFansDAO/xudtlogos/blob/f2557839ecde0409ba674516a62ae6752bc0daa9/public/tokens/token_list.json#L548\n - name: USDI\n script:\n code_hash: \"0xbfa35a9c38a676682b65ade8f02be164d48632281477e36f8dc2f41f79e56bfc\"\n hash_type: type\n args: \"0xd591ebdc69626647e056e13345fd830c8b876bb06aa07ba610479eb77153ea9f\"\n cell_deps:\n - type_id:\n code_hash: \"0x00000000000000000000000000000000000000000000000000545950455f4944\"\n hash_type: type\n args: \"0x9105ea69838511ca609518d27855c53fed1b5ffaff4cfb334f58b40627d211c4\"\n auto_accept_amount: 10000000\n\nservices:\n - fiber\n - rpc\n - ckb\n`;\n\nexport function getConfigTemplate(network: FiberNetwork): string {\n return network === 'mainnet' ? MAINNET_CONFIG_TEMPLATE_V071 : TESTNET_CONFIG_TEMPLATE_V071;\n}\n","import type { GraphChannelInfo, GraphNodeInfo } from '@fiber-pay/sdk';\nimport { shannonsToCkb, toHex } from '@fiber-pay/sdk';\nimport { Command } from 'commander';\nimport type { CliConfig } from '../lib/config.js';\nimport { formatAge, parseHexTimestampMs, printJsonSuccess, truncateMiddle } from '../lib/format.js';\nimport { createReadyRpcClient } from '../lib/rpc.js';\n\nfunction printGraphNodeListHuman(nodes: GraphNodeInfo[]): void {\n if (nodes.length === 0) {\n console.log('No nodes found in the graph.');\n return;\n }\n\n console.log(`Graph Nodes: ${nodes.length}`);\n console.log('');\n console.log('NODE ID ALIAS VERSION MIN FUNDING AGE');\n console.log('---------------------------------------------------------------------------------');\n\n for (const node of nodes) {\n const nodeId = truncateMiddle(node.node_id, 10, 8).padEnd(22, ' ');\n const alias = (node.node_name || '(unnamed)').slice(0, 20).padEnd(20, ' ');\n const version = (node.version || '?').slice(0, 10).padEnd(10, ' ');\n const minFunding = shannonsToCkb(node.auto_accept_min_ckb_funding_amount)\n .toString()\n .padStart(12, ' ');\n const age = formatAge(parseHexTimestampMs(node.timestamp));\n console.log(`${nodeId} ${alias} ${version} ${minFunding} ${age}`);\n }\n}\n\nfunction printGraphChannelListHuman(channels: GraphChannelInfo[]): void {\n if (channels.length === 0) {\n console.log('No channels found in the graph.');\n return;\n }\n\n console.log(`Graph Channels: ${channels.length}`);\n console.log('');\n console.log(\n 'OUTPOINT NODE1 NODE2 CAPACITY AGE',\n );\n console.log(\n '----------------------------------------------------------------------------------------------',\n );\n\n for (const ch of channels) {\n const outpoint = ch.channel_outpoint\n ? truncateMiddle(`${ch.channel_outpoint.tx_hash}:${ch.channel_outpoint.index}`, 10, 8)\n : 'n/a';\n const n1 = truncateMiddle(ch.node1, 10, 8).padEnd(22, ' ');\n const n2 = truncateMiddle(ch.node2, 10, 8).padEnd(22, ' ');\n const capacity = `${shannonsToCkb(ch.capacity)} CKB`.padStart(12, ' ');\n const age = formatAge(parseHexTimestampMs(ch.created_timestamp));\n console.log(`${outpoint.padEnd(22, ' ')} ${n1} ${n2} ${capacity} ${age}`);\n }\n}\n\nexport function createGraphCommand(config: CliConfig): Command {\n const graph = new Command('graph').description('Network graph queries (nodes & channels)');\n\n graph\n .command('nodes')\n .option('--limit <n>', 'Maximum number of nodes to return', '50')\n .option('--after <cursor>', 'Pagination cursor from a previous query')\n .option('--json')\n .action(async (options) => {\n const rpc = await createReadyRpcClient(config);\n const limit = toHex(BigInt(parseInt(options.limit, 10)));\n const result = await rpc.graphNodes({\n limit,\n after: options.after,\n });\n\n if (options.json) {\n printJsonSuccess({ nodes: result.nodes, lastCursor: result.last_cursor });\n } else {\n printGraphNodeListHuman(result.nodes);\n if (result.last_cursor && result.last_cursor !== '0x0') {\n console.log(`\\nNext cursor: ${result.last_cursor}`);\n }\n }\n });\n\n graph\n .command('channels')\n .option('--limit <n>', 'Maximum number of channels to return', '50')\n .option('--after <cursor>', 'Pagination cursor from a previous query')\n .option('--json')\n .action(async (options) => {\n const rpc = await createReadyRpcClient(config);\n const limit = toHex(BigInt(parseInt(options.limit, 10)));\n const result = await rpc.graphChannels({\n limit,\n after: options.after,\n });\n\n if (options.json) {\n printJsonSuccess({ channels: result.channels, lastCursor: result.last_cursor });\n } else {\n printGraphChannelListHuman(result.channels);\n if (result.last_cursor && result.last_cursor !== '0x0') {\n console.log(`\\nNext cursor: ${result.last_cursor}`);\n }\n }\n });\n\n return graph;\n}\n","import { ckbToShannons, type HexString, randomBytes32, shannonsToCkb, toHex } from '@fiber-pay/sdk';\nimport { Command } from 'commander';\nimport type { CliConfig } from '../lib/config.js';\nimport {\n extractInvoiceMetadata,\n parseHexTimestampMs,\n printInvoiceDetailHuman,\n printJsonError,\n printJsonSuccess,\n} from '../lib/format.js';\nimport { createReadyRpcClient, resolveRpcEndpoint } from '../lib/rpc.js';\nimport { tryCreateRuntimeInvoiceJob, waitForRuntimeJobTerminal } from '../lib/runtime-jobs.js';\n\nexport function createInvoiceCommand(config: CliConfig): Command {\n const invoice = new Command('invoice').description('Invoice lifecycle and status commands');\n\n invoice\n .command('create')\n .argument('[amount]')\n .option('--amount <ckb>')\n .option('--description <text>')\n .option('--expiry <minutes>')\n .option('--json')\n .action(async (amountArg, options) => {\n const rpc = await createReadyRpcClient(config);\n const json = Boolean(options.json);\n\n const amountCkb = options.amount\n ? parseFloat(options.amount)\n : amountArg\n ? parseFloat(amountArg)\n : 0;\n if (!amountCkb) {\n if (options.json) {\n printJsonError({\n code: 'INVOICE_CREATE_INPUT_INVALID',\n message: 'Amount required. Usage: invoice create --amount <CKB>',\n recoverable: true,\n suggestion: 'Provide a valid positive amount via `--amount <CKB>`.',\n });\n } else {\n console.error('Error: Amount required. Usage: invoice create --amount <CKB>');\n }\n process.exit(1);\n }\n\n const expirySeconds = (options.expiry ? parseInt(options.expiry, 10) : 60) * 60;\n const currency = config.network === 'mainnet' ? 'Fibb' : 'Fibt';\n\n const endpoint = resolveRpcEndpoint(config);\n if (endpoint.target === 'runtime-proxy') {\n const created = await tryCreateRuntimeInvoiceJob(endpoint.url, {\n params: {\n action: 'create',\n newInvoiceParams: {\n amount: ckbToShannons(amountCkb),\n currency,\n description: options.description,\n expiry: toHex(expirySeconds),\n payment_preimage: randomBytes32(),\n },\n waitForTerminal: false,\n },\n });\n\n if (created) {\n const job = await waitForRuntimeJobTerminal(endpoint.url, created.id, 60);\n if (job.state !== 'succeeded') {\n throw new Error(job.error?.message ?? `Invoice create job ${job.state}`);\n }\n\n const result = (job.result ?? {}) as {\n invoiceAddress?: string;\n paymentHash?: string;\n status?: string;\n };\n\n const payload = {\n jobId: job.id,\n invoice: result.invoiceAddress,\n paymentHash: result.paymentHash,\n amountCkb,\n expiresAt: new Date(Date.now() + expirySeconds * 1000).toISOString(),\n status: (result.status ?? 'Open').toLowerCase(),\n };\n\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log('Invoice created');\n console.log(` Job: ${payload.jobId}`);\n console.log(` Payment Hash: ${payload.paymentHash ?? 'n/a'}`);\n console.log(` Amount: ${payload.amountCkb} CKB`);\n console.log(` Expires At: ${payload.expiresAt}`);\n console.log(` Invoice: ${payload.invoice ?? 'n/a'}`);\n }\n return;\n }\n }\n\n const result = await rpc.newInvoice({\n amount: ckbToShannons(amountCkb),\n currency,\n description: options.description,\n expiry: toHex(expirySeconds),\n payment_preimage: randomBytes32(),\n });\n\n const payload = {\n invoice: result.invoice_address,\n paymentHash: result.invoice.data.payment_hash,\n amountCkb,\n expiresAt: new Date(Date.now() + expirySeconds * 1000).toISOString(),\n status: 'open',\n };\n\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log('Invoice created');\n console.log(` Payment Hash: ${payload.paymentHash}`);\n console.log(` Amount: ${payload.amountCkb} CKB`);\n console.log(` Expires At: ${payload.expiresAt}`);\n console.log(` Invoice: ${payload.invoice}`);\n }\n });\n\n invoice\n .command('get')\n .argument('<paymentHash>')\n .option('--json')\n .action(async (paymentHash, options) => {\n const rpc = await createReadyRpcClient(config);\n const result = await rpc.getInvoice({ payment_hash: paymentHash as HexString });\n const metadata = extractInvoiceMetadata(result.invoice);\n const createdAtMs = parseHexTimestampMs(result.invoice.data.timestamp);\n const output = {\n paymentHash,\n status: result.status,\n invoice: result.invoice_address,\n amountCkb: result.invoice.amount ? shannonsToCkb(result.invoice.amount) : undefined,\n currency: result.invoice.currency,\n description: metadata.description,\n createdAt: createdAtMs\n ? new Date(createdAtMs).toISOString()\n : result.invoice.data.timestamp,\n expiresAt: metadata.expiresAt,\n age: metadata.age,\n };\n\n if (options.json) {\n printJsonSuccess(output);\n } else {\n printInvoiceDetailHuman(output);\n }\n });\n\n invoice\n .command('parse')\n .argument('<invoiceString>')\n .option('--json')\n .action(async (invoiceString, options) => {\n const rpc = await createReadyRpcClient(config);\n const result = await rpc.parseInvoice({ invoice: invoiceString });\n if (options.json) {\n printJsonSuccess(result);\n } else {\n console.log('Invoice parsed');\n console.log(JSON.stringify(result, null, 2));\n }\n });\n\n invoice\n .command('cancel')\n .argument('<paymentHash>')\n .option('--json')\n .action(async (paymentHash, options) => {\n const rpc = await createReadyRpcClient(config);\n const json = Boolean(options.json);\n\n const endpoint = resolveRpcEndpoint(config);\n if (endpoint.target === 'runtime-proxy') {\n const created = await tryCreateRuntimeInvoiceJob(endpoint.url, {\n params: {\n action: 'cancel',\n cancelInvoiceParams: { payment_hash: paymentHash as HexString },\n },\n options: {\n idempotencyKey: `invoice:cancel:${paymentHash}`,\n },\n });\n\n if (created) {\n const job = await waitForRuntimeJobTerminal(endpoint.url, created.id, 60);\n if (job.state !== 'succeeded') {\n throw new Error(job.error?.message ?? `Invoice cancel job ${job.state}`);\n }\n\n const result = (job.result ?? {}) as {\n status?: string;\n invoiceAddress?: string;\n };\n\n const output = {\n jobId: job.id,\n paymentHash,\n status: result.status ?? 'Cancelled',\n invoice: result.invoiceAddress,\n };\n\n if (json) {\n printJsonSuccess(output);\n } else {\n console.log('Invoice cancelled');\n console.log(` Job: ${output.jobId}`);\n console.log(` Payment Hash: ${output.paymentHash}`);\n console.log(` Status: ${output.status}`);\n console.log(` Invoice: ${output.invoice ?? 'n/a'}`);\n }\n return;\n }\n }\n\n const result = await rpc.cancelInvoice({ payment_hash: paymentHash as HexString });\n const output = { paymentHash, status: result.status, invoice: result.invoice_address };\n if (json) {\n printJsonSuccess(output);\n } else {\n console.log('Invoice cancelled');\n console.log(` Payment Hash: ${output.paymentHash}`);\n console.log(` Status: ${output.status}`);\n console.log(` Invoice: ${output.invoice}`);\n }\n });\n\n invoice\n .command('settle')\n .argument('<paymentHash>')\n .requiredOption('--preimage <preimage>')\n .option('--json')\n .action(async (paymentHash, options) => {\n const rpc = await createReadyRpcClient(config);\n const json = Boolean(options.json);\n\n const endpoint = resolveRpcEndpoint(config);\n if (endpoint.target === 'runtime-proxy') {\n const created = await tryCreateRuntimeInvoiceJob(endpoint.url, {\n params: {\n action: 'settle',\n settleInvoiceParams: {\n payment_hash: paymentHash as HexString,\n payment_preimage: options.preimage as HexString,\n },\n },\n options: {\n idempotencyKey: `invoice:settle:${paymentHash}`,\n },\n });\n\n if (created) {\n const job = await waitForRuntimeJobTerminal(endpoint.url, created.id, 60);\n if (job.state !== 'succeeded') {\n throw new Error(job.error?.message ?? `Invoice settle job ${job.state}`);\n }\n\n const output = { jobId: job.id, paymentHash, message: 'Invoice settled.' };\n if (json) {\n printJsonSuccess(output);\n } else {\n console.log(output.message);\n console.log(` Job: ${output.jobId}`);\n console.log(` Payment Hash: ${output.paymentHash}`);\n }\n return;\n }\n }\n\n await rpc.settleInvoice({\n payment_hash: paymentHash as HexString,\n payment_preimage: options.preimage as HexString,\n });\n\n if (json) {\n printJsonSuccess({ paymentHash, message: 'Invoice settled.' });\n } else {\n console.log('Invoice settled');\n console.log(` Payment Hash: ${paymentHash}`);\n }\n });\n\n return invoice;\n}\n","import { existsSync } from 'node:fs';\nimport { Command } from 'commander';\nimport type { CliConfig } from '../lib/config.js';\nimport { printJsonError, printJsonSuccess } from '../lib/format.js';\nimport { readLastLines, resolvePersistedLogPaths } from '../lib/log-files.js';\nimport { resolveRpcEndpoint } from '../lib/rpc.js';\nimport type { RuntimeJobEventRecord, RuntimeJobRecord } from '../lib/runtime-jobs.js';\nimport { readRuntimeMeta } from '../lib/runtime-meta.js';\n\nexport function createJobCommand(config: CliConfig): Command {\n const job = new Command('job').description('Runtime job management commands');\n\n job\n .command('list')\n .option('--state <state>', 'Filter by job state')\n .option('--type <type>', 'Filter by job type (payment|invoice|channel)')\n .option('--limit <n>', 'Limit number of jobs')\n .option('--offset <n>', 'Offset for pagination')\n .option('--json')\n .action(async (options) => {\n const json = Boolean(options.json);\n const runtimeUrl = getRuntimeUrlOrExit(config, json);\n const query = new URLSearchParams();\n if (options.state) query.set('state', String(options.state));\n if (options.type) query.set('type', String(options.type));\n if (options.limit) query.set('limit', String(options.limit));\n if (options.offset) query.set('offset', String(options.offset));\n\n const response = await fetch(\n `${runtimeUrl}/jobs${query.toString() ? `?${query.toString()}` : ''}`,\n );\n if (!response.ok) {\n return handleHttpError(response, 'JOB_LIST_FAILED', json);\n }\n\n const payload = (await response.json()) as { jobs: RuntimeJobRecord[] };\n if (json) {\n printJsonSuccess(payload);\n return;\n }\n\n if (!payload.jobs.length) {\n console.log('No jobs found.');\n return;\n }\n\n console.log(`Jobs (${payload.jobs.length})`);\n for (const item of payload.jobs) {\n console.log(`- ${item.id}`);\n console.log(` Type: ${item.type}`);\n console.log(` State: ${item.state}`);\n if (item.idempotencyKey) console.log(` Key: ${item.idempotencyKey}`);\n if (typeof item.retryCount === 'number' && typeof item.maxRetries === 'number') {\n console.log(` Retry: ${item.retryCount}/${item.maxRetries}`);\n }\n }\n });\n\n job\n .command('get')\n .argument('<jobId>')\n .option('--json')\n .action(async (jobId, options) => {\n const json = Boolean(options.json);\n const runtimeUrl = getRuntimeUrlOrExit(config, json);\n const response = await fetch(`${runtimeUrl}/jobs/${jobId}`);\n if (!response.ok) {\n return handleHttpError(response, 'JOB_GET_FAILED', json);\n }\n\n const payload = (await response.json()) as RuntimeJobRecord;\n if (json) {\n printJsonSuccess(payload);\n return;\n }\n\n console.log('Job');\n console.log(` ID: ${payload.id}`);\n console.log(` Type: ${payload.type}`);\n console.log(` State: ${payload.state}`);\n if (payload.idempotencyKey) console.log(` Key: ${payload.idempotencyKey}`);\n if (typeof payload.retryCount === 'number' && typeof payload.maxRetries === 'number') {\n console.log(` Retry: ${payload.retryCount}/${payload.maxRetries}`);\n }\n if (payload.error?.message) {\n console.log(` Error: ${payload.error.message}`);\n }\n if (payload.result) {\n console.log(' Result:');\n console.log(` ${JSON.stringify(payload.result)}`);\n }\n });\n\n job\n .command('trace')\n .argument('<jobId>')\n .option('--tail <n>', 'Max lines to inspect per log file', '400')\n .option('--date <YYYY-MM-DD>', 'Date of log directory to search (default: today UTC)')\n .option('--json')\n .action(async (jobId, options) => {\n const json = Boolean(options.json);\n const tailInput = Number.parseInt(String(options.tail ?? '400'), 10);\n const tail = Number.isFinite(tailInput) && tailInput > 0 ? tailInput : 400;\n const date = options.date ? String(options.date).trim() : undefined;\n\n const runtimeUrl = getRuntimeUrlOrExit(config, json);\n const jobResponse = await fetch(`${runtimeUrl}/jobs/${jobId}`);\n if (!jobResponse.ok) {\n return handleHttpError(jobResponse, 'JOB_TRACE_GET_FAILED', json);\n }\n\n const eventsResponse = await fetch(`${runtimeUrl}/jobs/${jobId}/events`);\n if (!eventsResponse.ok) {\n return handleHttpError(eventsResponse, 'JOB_TRACE_EVENTS_FAILED', json);\n }\n\n const jobRecord = (await jobResponse.json()) as RuntimeJobRecord;\n const eventsPayload = (await eventsResponse.json()) as { events: RuntimeJobEventRecord[] };\n const tokens = collectTraceTokens(jobRecord, eventsPayload.events);\n\n const meta = readRuntimeMeta(config.dataDir);\n let logPaths: ReturnType<typeof resolvePersistedLogPaths>;\n try {\n logPaths = resolvePersistedLogPaths(config.dataDir, meta, date);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Invalid --date value.';\n if (json) {\n printJsonError({\n code: 'JOB_TRACE_DATE_INVALID',\n message,\n recoverable: true,\n suggestion: 'Retry with --date in YYYY-MM-DD format.',\n details: { date },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n const runtimeAlertMatches = collectRelatedLines(logPaths.runtimeAlerts, tokens, tail);\n const fnnStdoutMatches = collectRelatedLines(logPaths.fnnStdout, tokens, tail);\n const fnnStderrMatches = collectRelatedLines(logPaths.fnnStderr, tokens, tail);\n\n const result = {\n job: jobRecord,\n events: eventsPayload.events,\n trace: {\n tokens,\n logPaths,\n matches: {\n runtimeAlerts: runtimeAlertMatches,\n fnnStdout: fnnStdoutMatches,\n fnnStderr: fnnStderrMatches,\n },\n },\n };\n\n if (json) {\n printJsonSuccess(result);\n return;\n }\n\n console.log('Job trace');\n console.log(` Job ID: ${jobRecord.id}`);\n console.log(` Type: ${jobRecord.type}`);\n console.log(` State: ${jobRecord.state}`);\n if (jobRecord.idempotencyKey) {\n console.log(` Idempotency: ${jobRecord.idempotencyKey}`);\n }\n if (jobRecord.error?.message) {\n console.log(` Error: ${jobRecord.error.message}`);\n }\n console.log(` Events: ${eventsPayload.events.length}`);\n\n if (tokens.length > 0) {\n console.log(' Tokens:');\n for (const token of tokens) {\n console.log(` - ${token}`);\n }\n }\n\n printTraceSection('runtime.alerts', logPaths.runtimeAlerts, runtimeAlertMatches);\n printTraceSection('fnn.stdout', logPaths.fnnStdout, fnnStdoutMatches);\n printTraceSection('fnn.stderr', logPaths.fnnStderr, fnnStderrMatches);\n });\n\n job\n .command('events')\n .argument('<jobId>')\n .option('--with-data', 'Include event data payload in human-readable output')\n .option('--json')\n .action(async (jobId, options) => {\n const json = Boolean(options.json);\n const runtimeUrl = getRuntimeUrlOrExit(config, json);\n const response = await fetch(`${runtimeUrl}/jobs/${jobId}/events`);\n if (!response.ok) {\n return handleHttpError(response, 'JOB_EVENTS_FAILED', json);\n }\n\n const payload = (await response.json()) as { events: RuntimeJobEventRecord[] };\n if (json) {\n printJsonSuccess(payload);\n return;\n }\n\n if (!payload.events.length) {\n console.log('No events found for job.');\n return;\n }\n\n console.log(`Job events (${payload.events.length})`);\n for (const event of payload.events) {\n const timestamp = new Date(event.createdAt).toISOString();\n const transition = event.toState\n ? `${event.fromState ?? '(none)'} -> ${event.toState}`\n : (event.fromState ?? '(none)');\n console.log(`- ${timestamp} ${event.eventType} (${transition})`);\n if (options.withData && event.data !== undefined) {\n console.log(` data: ${JSON.stringify(event.data)}`);\n }\n }\n });\n\n job\n .command('cancel')\n .argument('<jobId>')\n .option('--json')\n .action(async (jobId, options) => {\n const json = Boolean(options.json);\n const runtimeUrl = getRuntimeUrlOrExit(config, json);\n const response = await fetch(`${runtimeUrl}/jobs/${jobId}`, { method: 'DELETE' });\n if (!response.ok) {\n return handleHttpError(response, 'JOB_CANCEL_FAILED', json);\n }\n\n const payload = { jobId, cancelled: true };\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log(`Job cancelled: ${jobId}`);\n }\n });\n\n return job;\n}\n\nfunction getRuntimeUrlOrExit(config: CliConfig, json: boolean): string {\n const endpoint = resolveRpcEndpoint(config);\n if (endpoint.target !== 'runtime-proxy') {\n const message =\n 'Runtime proxy is not active for the current profile/RPC URL. Start runtime first (fiber-pay runtime start --daemon).';\n if (json) {\n printJsonError({\n code: 'RUNTIME_PROXY_REQUIRED',\n message,\n recoverable: true,\n suggestion: 'Start runtime and retry the job command.',\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n return endpoint.url;\n}\n\nasync function handleHttpError(response: Response, code: string, json: boolean): Promise<never> {\n const body = await safeJson(response);\n const message = extractErrorMessage(body) ?? `HTTP ${response.status}`;\n\n if (json) {\n printJsonError({\n code,\n message,\n recoverable: response.status >= 500 || response.status === 404,\n suggestion: 'Check runtime status and job id, then retry.',\n details: {\n status: response.status,\n body,\n },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n}\n\nfunction extractErrorMessage(body: unknown): string | undefined {\n if (!body || typeof body !== 'object') {\n return undefined;\n }\n\n if ('error' in body) {\n const error = (body as { error?: unknown }).error;\n if (typeof error === 'string') {\n return error;\n }\n if (error && typeof error === 'object' && 'message' in error) {\n const message = (error as { message?: unknown }).message;\n if (typeof message === 'string') {\n return message;\n }\n }\n }\n\n if ('message' in body) {\n const message = (body as { message?: unknown }).message;\n if (typeof message === 'string') {\n return message;\n }\n }\n\n return undefined;\n}\n\nasync function safeJson(response: Response): Promise<unknown> {\n try {\n return await response.json();\n } catch {\n return undefined;\n }\n}\n\nfunction collectTraceTokens(job: RuntimeJobRecord, events: RuntimeJobEventRecord[]): string[] {\n const result = new Set<string>();\n addTraceToken(result, job.id);\n addTraceToken(result, job.idempotencyKey);\n\n collectStructuredTokens(result, job.params);\n collectStructuredTokens(result, job.result);\n collectStructuredTokens(result, job.error);\n\n for (const event of events) {\n addTraceToken(result, event.id);\n collectStructuredTokens(result, event.data);\n }\n\n return Array.from(result).slice(0, 20);\n}\n\nfunction addTraceToken(set: Set<string>, value: unknown): void {\n if (typeof value !== 'string') {\n return;\n }\n const normalized = value.trim();\n if (!normalized || normalized.length < 6) {\n return;\n }\n if (normalized.includes(' ')) {\n return;\n }\n if (normalized.length <= 128) {\n set.add(normalized);\n }\n}\n\nfunction collectStructuredTokens(set: Set<string>, input: unknown, depth = 0): void {\n if (depth > 3 || input === null || input === undefined) {\n return;\n }\n if (typeof input === 'string') {\n if (input.startsWith('0x') || input.includes('peer') || input.includes('channel')) {\n addTraceToken(set, input);\n }\n return;\n }\n if (Array.isArray(input)) {\n for (const item of input) {\n collectStructuredTokens(set, item, depth + 1);\n }\n return;\n }\n if (typeof input === 'object') {\n for (const value of Object.values(input as Record<string, unknown>)) {\n collectStructuredTokens(set, value, depth + 1);\n }\n }\n}\n\nfunction collectRelatedLines(filePath: string, tokens: string[], tail: number): string[] {\n if (!existsSync(filePath)) {\n return [];\n }\n const lines = readLastLines(filePath, tail);\n if (tokens.length === 0) {\n return lines.slice(-Math.min(30, lines.length));\n }\n\n const related = lines.filter((line) => tokens.some((token) => line.includes(token)));\n if (related.length > 0) {\n return related.slice(-Math.min(80, related.length));\n }\n\n return lines.slice(-Math.min(20, lines.length));\n}\n\nfunction printTraceSection(title: string, filePath: string, lines: string[]): void {\n console.log(`\\n${title}: ${filePath}`);\n if (!existsSync(filePath)) {\n console.log(' (file not found)');\n return;\n }\n if (lines.length === 0) {\n console.log(' (no related lines)');\n return;\n }\n for (const line of lines.slice(-20)) {\n console.log(` ${line}`);\n }\n}\n","import {\n appendFileSync,\n closeSync,\n createReadStream,\n existsSync,\n mkdirSync,\n openSync,\n readdirSync,\n readSync,\n statSync,\n} from 'node:fs';\nimport { join } from 'node:path';\nimport type { RuntimeMeta } from './runtime-meta.js';\n\nexport interface PersistedLogPaths {\n runtimeAlerts: string;\n fnnStdout: string;\n fnnStderr: string;\n}\n\nexport type PersistedLogSource = 'runtime' | 'fnn-stdout' | 'fnn-stderr';\nexport type PersistedLogSourceOption = PersistedLogSource | 'all';\n\nexport interface PersistedLogTarget {\n source: PersistedLogSource;\n title: 'runtime.alerts' | 'fnn.stdout' | 'fnn.stderr';\n path: string;\n}\n\nconst DATE_DIR_PATTERN = /^\\d{4}-\\d{2}-\\d{2}$/;\n\n/**\n * Returns the current UTC date as YYYY-MM-DD string.\n */\nexport function todayDateString(): string {\n const now = new Date();\n const y = now.getUTCFullYear();\n const m = String(now.getUTCMonth() + 1).padStart(2, '0');\n const d = String(now.getUTCDate()).padStart(2, '0');\n return `${y}-${m}-${d}`;\n}\n\nexport interface ResolveLogDirOptions {\n logsBaseDir?: string;\n ensureExists?: boolean;\n}\n\nexport function validateLogDate(date: string): string {\n const value = date.trim();\n if (!DATE_DIR_PATTERN.test(value)) {\n throw new Error(`Invalid date '${value}'. Expected format YYYY-MM-DD.`);\n }\n if (value.includes('/') || value.includes('\\\\') || value.includes('..')) {\n throw new Error(`Invalid date '${value}'. Path separators or '..' are not allowed.`);\n }\n return value;\n}\n\n/**\n * Returns the path to a date-based log directory: `<data-dir>/logs/<YYYY-MM-DD>/`.\n * Creates the directory if it does not exist.\n */\nexport function resolveLogDirForDate(dataDir: string, date?: string): string {\n return resolveLogDirForDateWithOptions(dataDir, date, {});\n}\n\nexport function resolveLogDirForDateWithOptions(\n dataDir: string,\n date: string | undefined,\n options: ResolveLogDirOptions,\n): string {\n const dateStr = date ?? todayDateString();\n const logsBaseDir = options.logsBaseDir ?? join(dataDir, 'logs');\n if (date !== undefined) {\n validateLogDate(dateStr);\n }\n const dir = join(logsBaseDir, dateStr);\n const ensureExists = options.ensureExists ?? true;\n if (ensureExists) {\n mkdirSync(dir, { recursive: true });\n }\n return dir;\n}\n\n/**\n * Resolve persisted log paths for a given date.\n *\n * When `date` is provided, always returns paths under `<data-dir>/logs/<date>/`.\n * When `date` is omitted and `meta` provides explicit paths, those are used for\n * backward compatibility. Otherwise defaults to today's date directory.\n */\nexport function resolvePersistedLogPaths(\n dataDir: string,\n meta?: RuntimeMeta | null,\n date?: string,\n): PersistedLogPaths {\n const logsBaseDir = meta?.logsBaseDir ?? join(dataDir, 'logs');\n\n if (date) {\n const dir = resolveLogDirForDateWithOptions(dataDir, date, {\n logsBaseDir,\n ensureExists: false,\n });\n return {\n runtimeAlerts: join(dir, 'runtime.alerts.jsonl'),\n fnnStdout: join(dir, 'fnn.stdout.log'),\n fnnStderr: join(dir, 'fnn.stderr.log'),\n };\n }\n\n if (meta?.alertLogFilePath || meta?.fnnStdoutLogPath || meta?.fnnStderrLogPath) {\n const defaultDir = resolveLogDirForDateWithOptions(dataDir, undefined, {\n logsBaseDir,\n ensureExists: false,\n });\n return {\n runtimeAlerts: meta.alertLogFilePath ?? join(defaultDir, 'runtime.alerts.jsonl'),\n fnnStdout: meta.fnnStdoutLogPath ?? join(defaultDir, 'fnn.stdout.log'),\n fnnStderr: meta.fnnStderrLogPath ?? join(defaultDir, 'fnn.stderr.log'),\n };\n }\n\n const dir = resolveLogDirForDateWithOptions(dataDir, undefined, {\n logsBaseDir,\n ensureExists: false,\n });\n return {\n runtimeAlerts: join(dir, 'runtime.alerts.jsonl'),\n fnnStdout: join(dir, 'fnn.stdout.log'),\n fnnStderr: join(dir, 'fnn.stderr.log'),\n };\n}\n\n/**\n * List available log dates by scanning `<data-dir>/logs/` for YYYY-MM-DD directories.\n * Returns date strings sorted newest-first.\n */\nexport function listLogDates(dataDir: string, logsBaseDir?: string): string[] {\n const logsDir = logsBaseDir ?? join(dataDir, 'logs');\n if (!existsSync(logsDir)) {\n return [];\n }\n\n const entries = readdirSync(logsDir, { withFileTypes: true });\n const dates = entries\n .filter((entry) => entry.isDirectory() && DATE_DIR_PATTERN.test(entry.name))\n .map((entry) => entry.name);\n\n dates.sort((a, b) => (a > b ? -1 : a < b ? 1 : 0));\n return dates;\n}\n\n/**\n * Append text to a log file inside today's date directory.\n * Creates the date directory on first write each day.\n */\nexport function appendToTodayLog(dataDir: string, filename: string, text: string): void {\n const dir = resolveLogDirForDate(dataDir);\n appendFileSync(join(dir, filename), text, 'utf-8');\n}\n\nexport function resolvePersistedLogTargets(\n paths: PersistedLogPaths,\n source: PersistedLogSourceOption,\n): PersistedLogTarget[] {\n const all: PersistedLogTarget[] = [\n {\n source: 'runtime',\n title: 'runtime.alerts',\n path: paths.runtimeAlerts,\n },\n {\n source: 'fnn-stdout',\n title: 'fnn.stdout',\n path: paths.fnnStdout,\n },\n {\n source: 'fnn-stderr',\n title: 'fnn.stderr',\n path: paths.fnnStderr,\n },\n ];\n\n if (source === 'all') {\n return all;\n }\n\n return all.filter((target) => target.source === source);\n}\n\nexport function readLastLines(filePath: string, maxLines: number): string[] {\n if (!existsSync(filePath)) {\n return [];\n }\n\n if (!Number.isFinite(maxLines) || maxLines <= 0) {\n return [];\n }\n\n let fd: number | undefined;\n try {\n fd = openSync(filePath, 'r');\n const size = statSync(filePath).size;\n if (size <= 0) {\n return [];\n }\n\n const chunkSize = 64 * 1024;\n let position = size;\n const chunks: string[] = [];\n let newlineCount = 0;\n\n while (position > 0 && newlineCount <= maxLines) {\n const start = Math.max(0, position - chunkSize);\n const bytesToRead = position - start;\n const buffer = Buffer.alloc(bytesToRead);\n const bytesRead = readSync(fd, buffer, 0, bytesToRead, start);\n const chunk = buffer.toString('utf8', 0, bytesRead);\n chunks.unshift(chunk);\n\n for (let index = 0; index < chunk.length; index += 1) {\n if (chunk.charCodeAt(index) === 10) {\n newlineCount += 1;\n }\n }\n\n position = start;\n }\n\n const content = chunks.join('');\n const lines = content.split(/\\r?\\n/).filter((line) => line.length > 0);\n return lines.slice(-maxLines);\n } finally {\n if (fd !== undefined) {\n try {\n closeSync(fd);\n } catch {\n // ignore close errors\n }\n }\n }\n}\n\nexport interface ReadAppendedLinesResult {\n lines: string[];\n nextOffset: number;\n remainder: string;\n}\n\nexport async function readAppendedLines(\n filePath: string,\n offset: number,\n remainder = '',\n): Promise<ReadAppendedLinesResult> {\n if (!existsSync(filePath)) {\n return { lines: [], nextOffset: 0, remainder: '' };\n }\n\n const size = statSync(filePath).size;\n const safeOffset = size < offset ? 0 : offset;\n if (safeOffset >= size) {\n return { lines: [], nextOffset: size, remainder };\n }\n\n const stream = createReadStream(filePath, {\n encoding: 'utf8',\n start: safeOffset,\n end: size - 1,\n });\n\n const lines: string[] = [];\n let pending = remainder;\n let bytesReadTotal = 0;\n\n for await (const chunk of stream) {\n const chunkText = String(chunk);\n bytesReadTotal += Buffer.byteLength(chunkText, 'utf8');\n\n const merged = `${pending}${chunkText}`;\n const parts = merged.split(/\\r?\\n/);\n pending = parts.pop() ?? '';\n\n for (const line of parts) {\n if (line.length > 0) {\n lines.push(line);\n }\n }\n }\n\n return {\n lines,\n nextOffset: safeOffset + bytesReadTotal,\n remainder: pending,\n };\n}\n","import { existsSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { type Alert, formatRuntimeAlert } from '@fiber-pay/runtime';\nimport { Command } from 'commander';\nimport type { CliConfig } from '../lib/config.js';\nimport { printJsonError, printJsonSuccess } from '../lib/format.js';\nimport {\n listLogDates,\n type PersistedLogSourceOption,\n readAppendedLines,\n readLastLines,\n resolvePersistedLogPaths,\n resolvePersistedLogTargets,\n} from '../lib/log-files.js';\nimport { readRuntimeMeta } from '../lib/runtime-meta.js';\n\nconst ALLOWED_SOURCES = new Set<PersistedLogSourceOption>([\n 'all',\n 'runtime',\n 'fnn-stdout',\n 'fnn-stderr',\n]);\nconst DATE_DIR_PATTERN = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nfunction parseRuntimeAlertLine(line: string): Alert | null {\n try {\n const parsed = JSON.parse(line) as Alert;\n if (!parsed || typeof parsed !== 'object') {\n return null;\n }\n return parsed;\n } catch {\n return null;\n }\n}\n\nfunction formatRuntimeAlertHuman(line: string): string {\n const parsed = parseRuntimeAlertLine(line);\n if (!parsed) {\n return line;\n }\n\n return formatRuntimeAlert(parsed);\n}\n\nfunction coerceJsonLineForOutput(source: PersistedLogSourceOption, line: string): unknown {\n if (source !== 'runtime') {\n return line;\n }\n return parseRuntimeAlertLine(line) ?? line;\n}\n\nexport function createLogsCommand(config: CliConfig): Command {\n return new Command('logs')\n .alias('log')\n .description('View persisted runtime/fnn logs')\n .option('--source <source>', 'Log source: all|runtime|fnn-stdout|fnn-stderr', 'all')\n .option('--tail <n>', 'Number of recent lines per source', '80')\n .option('--date <YYYY-MM-DD>', 'Date of log directory to read (default: today UTC)')\n .option('--list-dates', 'List available log dates and exit')\n .option('--follow', 'Keep streaming appended log lines (human output mode only)')\n .option('--interval-ms <ms>', 'Polling interval for --follow mode', '1000')\n .option('--json')\n .action(async (options) => {\n const json = Boolean(options.json);\n const follow = Boolean(options.follow);\n const listDates = Boolean(options.listDates);\n const date = options.date ? String(options.date).trim() : undefined;\n const meta = readRuntimeMeta(config.dataDir);\n\n if (follow && date) {\n const message = \"--follow cannot be used with --date. --follow only streams today's logs.\";\n if (json) {\n printJsonError({\n code: 'LOG_FOLLOW_DATE_UNSUPPORTED',\n message,\n recoverable: true,\n suggestion: 'Remove --date or remove --follow and retry.',\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n\n // --list-dates mode: show available log dates and exit\n if (listDates) {\n const logsDir = meta?.logsBaseDir ?? join(config.dataDir, 'logs');\n const dates = listLogDates(config.dataDir, logsDir);\n if (json) {\n printJsonSuccess({ dates, logsDir });\n } else {\n if (dates.length === 0) {\n console.log('No log dates found.');\n } else {\n console.log(`Log dates (${dates.length}):`);\n for (const date of dates) {\n console.log(` ${date}`);\n }\n console.log(`\\nLogs directory: ${logsDir}`);\n }\n }\n return;\n }\n\n const sourceInput = String(options.source ?? 'all')\n .trim()\n .toLowerCase();\n\n if (json && follow) {\n const message = '--follow is not supported with --json. Use human mode for streaming logs.';\n printJsonError({\n code: 'LOG_FOLLOW_JSON_UNSUPPORTED',\n message,\n recoverable: true,\n suggestion: 'Remove --json or remove --follow and retry.',\n });\n process.exit(1);\n }\n\n if (!ALLOWED_SOURCES.has(sourceInput as PersistedLogSourceOption)) {\n const message =\n 'Invalid --source value. Expected one of: all, runtime, fnn-stdout, fnn-stderr.';\n if (json) {\n printJsonError({\n code: 'LOG_SOURCE_INVALID',\n message,\n recoverable: true,\n suggestion: 'Retry with --source all|runtime|fnn-stdout|fnn-stderr.',\n details: { source: sourceInput },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n\n const source = sourceInput as PersistedLogSourceOption;\n const tailInput = Number.parseInt(String(options.tail ?? '80'), 10);\n const tail = Number.isFinite(tailInput) && tailInput > 0 ? tailInput : 80;\n const intervalInput = Number.parseInt(String(options.intervalMs ?? '1000'), 10);\n const intervalMs = Number.isFinite(intervalInput) && intervalInput > 0 ? intervalInput : 1000;\n\n let paths: ReturnType<typeof resolvePersistedLogPaths>;\n try {\n paths = resolvePersistedLogPaths(config.dataDir, meta, date);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Invalid --date value.';\n if (json) {\n printJsonError({\n code: 'LOG_DATE_INVALID',\n message,\n recoverable: true,\n suggestion: 'Retry with --date in YYYY-MM-DD format.',\n details: { date },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n\n const targets = resolvePersistedLogTargets(paths, source);\n const displayDate = date ?? inferDateFromPaths(paths);\n\n if (source !== 'all' && targets.length === 1 && !existsSync(targets[0].path)) {\n const dateLabel = displayDate ? ` on ${displayDate}` : '';\n const message = `Log file not found for source ${source}${dateLabel}: ${targets[0].path}`;\n if (json) {\n printJsonError({\n code: 'LOG_FILE_NOT_FOUND',\n message,\n recoverable: true,\n suggestion:\n 'Start node/runtime or generate activity, then retry logs command. Use --list-dates to see available dates.',\n details: { source, date: displayDate ?? null, path: targets[0].path },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n\n const entries = [] as Array<{\n source: (typeof targets)[number]['source'];\n title: (typeof targets)[number]['title'];\n path: string;\n exists: boolean;\n lineCount: number;\n lines: string[];\n jsonLines: unknown[];\n }>;\n\n for (const target of targets) {\n const exists = existsSync(target.path);\n let lines: string[] = [];\n if (exists) {\n try {\n lines = readLastLines(target.path, tail);\n } catch (error) {\n const message =\n error instanceof Error ? error.message : `Failed to read log file: ${target.path}`;\n if (json) {\n printJsonError({\n code: 'LOG_READ_FAILED',\n message,\n recoverable: true,\n suggestion: 'Check log file permissions and retry.',\n details: { source: target.source, path: target.path },\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n }\n\n entries.push({\n source: target.source,\n title: target.title,\n path: target.path,\n exists,\n lineCount: lines.length,\n lines,\n jsonLines: lines.map((line) => coerceJsonLineForOutput(target.source, line)),\n });\n }\n\n if (json) {\n printJsonSuccess({\n source,\n tail,\n date: displayDate ?? null,\n entries: entries.map((entry) => ({\n source: entry.source,\n title: entry.title,\n path: entry.path,\n exists: entry.exists,\n lineCount: entry.lineCount,\n lines: entry.jsonLines,\n })),\n });\n return;\n }\n\n const headerDate = displayDate ? `, date: ${displayDate}` : '';\n console.log(`Logs (source: ${source}${headerDate}, tail: ${tail})`);\n for (const entry of entries) {\n console.log(`\\n${entry.title}: ${entry.path}`);\n if (!entry.exists) {\n console.log(' (file not found)');\n continue;\n }\n if (entry.lines.length === 0) {\n console.log(' (no lines)');\n continue;\n }\n for (const line of entry.lines) {\n const output = entry.source === 'runtime' ? formatRuntimeAlertHuman(line) : line;\n console.log(` ${output}`);\n }\n }\n\n if (!follow) {\n return;\n }\n\n console.log(`\\nFollowing logs (interval: ${intervalMs}ms). Press Ctrl+C to stop.`);\n\n const states = new Map(\n entries.map((entry) => [\n entry.source,\n {\n title: entry.title,\n path: entry.path,\n offset: entry.exists ? statSync(entry.path).size : 0,\n remainder: '',\n },\n ]),\n );\n\n // Keep process alive for follow mode.\n await new Promise<void>((resolve) => {\n let stopped = false;\n const stop = () => {\n if (stopped) return;\n stopped = true;\n clearInterval(timer);\n process.off('SIGINT', stop);\n process.off('SIGTERM', stop);\n console.log('\\nStopped following logs.');\n resolve();\n };\n\n let polling = false;\n const timer = setInterval(() => {\n if (polling) {\n return;\n }\n polling = true;\n\n void (async () => {\n for (const target of targets) {\n const state = states.get(target.source);\n if (!state) continue;\n\n if (!existsSync(state.path)) {\n state.offset = 0;\n state.remainder = '';\n continue;\n }\n\n const result = await readAppendedLines(state.path, state.offset, state.remainder);\n const newLines = result.lines;\n if (newLines.length === 0) {\n state.offset = result.nextOffset;\n state.remainder = result.remainder;\n continue;\n }\n\n for (const line of newLines) {\n const output = target.source === 'runtime' ? formatRuntimeAlertHuman(line) : line;\n console.log(`[${state.title}] ${output}`);\n }\n state.offset = result.nextOffset;\n state.remainder = result.remainder;\n }\n })()\n .catch((error) => {\n const message =\n error instanceof Error ? error.message : 'Failed to read appended logs';\n console.error(`Error: ${message}`);\n })\n .finally(() => {\n polling = false;\n });\n }, intervalMs);\n\n process.on('SIGINT', stop);\n process.on('SIGTERM', stop);\n });\n });\n}\n\nfunction inferDateFromPaths(paths: {\n runtimeAlerts: string;\n fnnStdout: string;\n fnnStderr: string;\n}): string | undefined {\n const candidate = paths.runtimeAlerts.split('/').at(-2);\n if (!candidate || !DATE_DIR_PATTERN.test(candidate)) {\n return undefined;\n }\n\n const stdoutDate = paths.fnnStdout.split('/').at(-2);\n const stderrDate = paths.fnnStderr.split('/').at(-2);\n if (stdoutDate !== candidate || stderrDate !== candidate) {\n return undefined;\n }\n\n return candidate;\n}\n","import { Command } from 'commander';\nimport type { CliConfig } from '../lib/config.js';\nimport { runNodeInfoCommand } from '../lib/node-info.js';\nimport { runNodeNetworkCommand } from '../lib/node-network.js';\nimport { runNodeStartCommand } from '../lib/node-start.js';\nimport { runNodeReadyCommand, runNodeStatusCommand } from '../lib/node-status.js';\nimport { runNodeStopCommand } from '../lib/node-stop.js';\nimport { runNodeUpgradeCommand } from '../lib/node-upgrade.js';\n\nexport function createNodeCommand(config: CliConfig): Command {\n const node = new Command('node').description('Node management');\n\n node\n .command('start')\n .option('--daemon', 'Start node in detached background mode (node + runtime)')\n .option('--runtime-proxy-listen <host:port>', 'Runtime monitor proxy listen address')\n .option('--event-stream <format>', 'Event stream format for --json mode (jsonl)', 'jsonl')\n .option('--quiet-fnn', 'Do not mirror fnn stdout/stderr to console; keep file persistence')\n .option('--json')\n .action(async (options) => {\n await runNodeStartCommand(config, options);\n });\n\n node\n .command('stop')\n .option('--json')\n .action(async (options) => {\n await runNodeStopCommand(config, options);\n });\n\n node\n .command('status')\n .option('--json')\n .action(async (options) => {\n await runNodeStatusCommand(config, options);\n });\n\n node\n .command('network')\n .description('Display comprehensive network topology and connections')\n .option('--json')\n .action(async (options) => {\n await runNodeNetworkCommand(config, options);\n });\n\n node\n .command('info')\n .description('Display information about the running node')\n .option('--json')\n .action(async (options) => {\n await runNodeInfoCommand(config, options);\n });\n\n node\n .command('ready')\n .description('Agent-oriented readiness summary for automation')\n .option('--json')\n .action(async (options) => {\n await runNodeReadyCommand(config, options);\n });\n\n node\n .command('upgrade')\n .description('Upgrade the Fiber node binary and migrate the database if needed')\n .option('--version <version>', 'Target Fiber version (default: latest)')\n .option('--no-backup', 'Skip creating a store backup before migration')\n .option('--check-only', 'Only check if migration is needed, do not migrate')\n .option(\n '--force-migrate',\n 'Force migration attempt even when compatibility check reports incompatible data',\n )\n .option('--json')\n .action(async (options) => {\n await runNodeUpgradeCommand(config, options);\n });\n\n return node;\n}\n","import type { CliConfig } from './config.js';\nimport { printJsonSuccess, sanitizeForTerminal } from './format.js';\nimport { createReadyRpcClient } from './rpc.js';\n\nexport interface NodeInfoOptions {\n json?: boolean;\n}\n\nexport async function runNodeInfoCommand(\n config: CliConfig,\n options: NodeInfoOptions,\n): Promise<void> {\n const rpc = await createReadyRpcClient(config);\n const nodeInfo = await rpc.nodeInfo();\n\n if (options.json) {\n printJsonSuccess(nodeInfo);\n return;\n }\n\n console.log('✅ Node info retrieved');\n console.log(` Version: ${nodeInfo.version}`);\n console.log(` Commit: ${nodeInfo.commit_hash}`);\n console.log(` Node ID: ${nodeInfo.node_id}`);\n if (nodeInfo.features.length > 0) {\n console.log(' Features:');\n for (const feature of nodeInfo.features) {\n console.log(` - ${sanitizeForTerminal(feature)}`);\n }\n }\n console.log(` Name: ${sanitizeForTerminal(nodeInfo.node_name ?? '-')}`);\n if (nodeInfo.addresses.length > 0) {\n console.log(' Addresses:');\n for (const address of nodeInfo.addresses) {\n console.log(` - ${sanitizeForTerminal(address)}`);\n }\n }\n console.log(` Chain Hash: ${nodeInfo.chain_hash}`);\n console.log(` Channels: ${BigInt(nodeInfo.channel_count)}`);\n console.log(` Pending Channels: ${BigInt(nodeInfo.pending_channel_count)}`);\n console.log(` Peers: ${BigInt(nodeInfo.peers_count)}`);\n if (nodeInfo.udt_cfg_infos.length > 0) {\n console.log(' UDT Configs:');\n for (const udt of nodeInfo.udt_cfg_infos) {\n console.log(` - Name: ${sanitizeForTerminal(udt.name)}`);\n console.log(` Script: ${JSON.stringify(udt.script, null, 6)}`);\n if (udt.auto_accept_amount) {\n console.log(` Auto Accept Amount: ${BigInt(udt.auto_accept_amount)}`);\n }\n if (udt.cell_deps.length > 0) {\n console.log(' Cell Deps:');\n for (const dep of udt.cell_deps) {\n console.log(\n ` - Cell Dep: ${dep.cell_dep ? JSON.stringify(dep.cell_dep) : 'null'}`,\n );\n console.log(` Type ID: ${dep.type_id ? JSON.stringify(dep.type_id) : 'null'}`);\n }\n }\n }\n }\n}\n","import type { Channel, GraphChannelInfo, GraphNodeInfo, PeerInfo } from '@fiber-pay/sdk';\nimport { shannonsToCkb, toHex } from '@fiber-pay/sdk';\nimport type { CliConfig } from './config.js';\nimport {\n formatShannonsAsCkb,\n printJsonSuccess,\n sanitizeForTerminal,\n truncateMiddle,\n} from './format.js';\nimport { createReadyRpcClient } from './rpc.js';\n\nexport interface NodeNetworkOptions {\n json?: boolean;\n}\n\nexport interface EnrichedPeerInfo extends PeerInfo {\n nodeInfo?: GraphNodeInfo;\n}\n\nexport interface EnrichedChannelInfo extends Channel {\n peerNodeInfo?: GraphNodeInfo;\n graphChannelInfo?: GraphChannelInfo;\n}\n\nexport interface NodeNetworkData {\n localNodeId: string;\n peers: EnrichedPeerInfo[];\n channels: EnrichedChannelInfo[];\n graphNodes: GraphNodeInfo[];\n graphChannels: GraphChannelInfo[];\n summary: {\n connectedPeers: number;\n activeChannels: number;\n totalChannelCapacity: string;\n };\n}\n\nexport async function runNodeNetworkCommand(\n config: CliConfig,\n options: NodeNetworkOptions,\n): Promise<void> {\n const rpc = await createReadyRpcClient(config);\n\n // Fetch all required data\n const [nodeInfo, localPeers, localChannels, graphNodes, graphChannels] = await Promise.all([\n rpc.nodeInfo(),\n rpc.listPeers(),\n rpc.listChannels({ include_closed: false }),\n rpc.graphNodes({}),\n rpc.graphChannels({}),\n ]);\n\n // Create lookup maps for efficient data enrichment\n const graphNodesMap = new Map<string, GraphNodeInfo>();\n for (const node of graphNodes.nodes) {\n graphNodesMap.set(node.node_id, node);\n }\n\n // Create peer_id to node_id mapping from connected peers\n const peerIdToNodeIdMap = new Map<string, string>();\n for (const peer of localPeers.peers) {\n peerIdToNodeIdMap.set(peer.peer_id, peer.pubkey);\n }\n\n const graphChannelsMap = new Map<string, GraphChannelInfo>();\n for (const channel of graphChannels.channels) {\n if (channel.channel_outpoint) {\n const outpointKey = `${channel.channel_outpoint.tx_hash}:${channel.channel_outpoint.index}`;\n graphChannelsMap.set(outpointKey, channel);\n }\n }\n\n // Enrich peer information\n const enrichedPeers: EnrichedPeerInfo[] = localPeers.peers.map((peer) => ({\n ...peer,\n nodeInfo: graphNodesMap.get(peer.pubkey),\n }));\n\n // Enrich channel information\n const enrichedChannels: EnrichedChannelInfo[] = localChannels.channels.map((channel) => {\n // Try to find node_id from peer_id mapping first, then fallback to direct lookup\n const nodeId = peerIdToNodeIdMap.get(channel.peer_id) || channel.peer_id;\n const peerNodeInfo = graphNodesMap.get(nodeId);\n let graphChannelInfo: GraphChannelInfo | undefined;\n\n // Try to find the graph channel info by matching outpoint\n if (channel.channel_outpoint) {\n const outpointKey = `${channel.channel_outpoint.tx_hash}:${channel.channel_outpoint.index}`;\n graphChannelInfo = graphChannelsMap.get(outpointKey);\n }\n\n return {\n ...channel,\n peerNodeInfo,\n graphChannelInfo,\n };\n });\n\n // Calculate summary statistics\n const activeChannels = enrichedChannels.filter((ch) => ch.state?.state_name === 'CHANNEL_READY');\n const totalChannelCapacityShannons = activeChannels.reduce((sum, ch) => {\n const capacity = ch.graphChannelInfo?.capacity\n ? ch.graphChannelInfo.capacity\n : toHex(BigInt(ch.local_balance) + BigInt(ch.remote_balance));\n return sum + BigInt(capacity);\n }, 0n);\n const totalChannelCapacity = formatShannonsAsCkb(totalChannelCapacityShannons, 1);\n\n const networkData: NodeNetworkData = {\n localNodeId: nodeInfo.node_id,\n peers: enrichedPeers,\n channels: enrichedChannels,\n graphNodes: graphNodes.nodes,\n graphChannels: graphChannels.channels,\n summary: {\n connectedPeers: enrichedPeers.length,\n activeChannels: activeChannels.length,\n totalChannelCapacity,\n },\n };\n\n if (options.json) {\n printJsonSuccess(networkData);\n return;\n }\n\n // Human-readable output\n printNodeNetworkHuman(networkData);\n}\n\nfunction printNodeNetworkHuman(data: NodeNetworkData): void {\n console.log('Node Network Overview');\n console.log('=====================');\n console.log('');\n console.log(`Connected Peers: ${data.summary.connectedPeers}`);\n console.log(`Active Channels: ${data.summary.activeChannels}`);\n console.log(`Total Channel Capacity: ${data.summary.totalChannelCapacity} CKB`);\n console.log('');\n\n // Print peers table\n if (data.peers.length > 0) {\n console.log('Peers:');\n console.log(' PEER_ID ALIAS ADDRESS VERSION');\n console.log(\n ' --------------------------------------------------------------------------------',\n );\n\n for (const peer of data.peers) {\n const peerId = truncateMiddle(peer.peer_id, 10, 8).padEnd(22, ' ');\n const alias = sanitizeForTerminal(peer.nodeInfo?.node_name || '(unnamed)')\n .slice(0, 20)\n .padEnd(20, ' ');\n const address = truncateMiddle(sanitizeForTerminal(peer.address), 15, 8).padEnd(25, ' ');\n const version = sanitizeForTerminal(peer.nodeInfo?.version || '?')\n .slice(0, 8)\n .padEnd(8, ' ');\n console.log(` ${peerId} ${alias} ${address} ${version}`);\n }\n console.log('');\n }\n\n // Print channels table\n if (data.channels.length > 0) {\n console.log('Channels:');\n console.log(\n ' CHANNEL_ID PEER_ALIAS STATE LOCAL_BAL REMOTE_BAL CAPACITY',\n );\n console.log(\n ' -----------------------------------------------------------------------------------------------',\n );\n\n for (const channel of data.channels) {\n const channelId = truncateMiddle(channel.channel_id, 10, 8).padEnd(22, ' ');\n const peerAlias = sanitizeForTerminal(channel.peerNodeInfo?.node_name || '(unnamed)')\n .slice(0, 18)\n .padEnd(18, ' ');\n const state = (channel.state?.state_name || 'UNKNOWN').slice(0, 13).padEnd(13, ' ');\n const localBal = shannonsToCkb(channel.local_balance).toFixed(1).padStart(11, ' ');\n const remoteBal = shannonsToCkb(channel.remote_balance).toFixed(1).padStart(11, ' ');\n const capacity = channel.graphChannelInfo?.capacity\n ? shannonsToCkb(channel.graphChannelInfo.capacity).toFixed(1).padStart(8, ' ')\n : shannonsToCkb(toHex(BigInt(channel.local_balance) + BigInt(channel.remote_balance)))\n .toFixed(1)\n .padStart(8, ' ');\n\n console.log(` ${channelId} ${peerAlias} ${state} ${localBal} ${remoteBal} ${capacity}`);\n }\n }\n}\n","import { spawn } from 'node:child_process';\nimport { mkdirSync } from 'node:fs';\nimport { join } from 'node:path';\nimport {\n createKeyManager,\n ensureFiberBinary,\n type FiberNodeConfig,\n ProcessManager,\n} from '@fiber-pay/node';\nimport { startRuntimeService } from '@fiber-pay/runtime';\nimport { getBinaryManagerInstallDirOrThrow, resolveBinaryPath } from './binary-path.js';\nimport { autoConnectBootnodes, extractBootnodeAddrs } from './bootnode.js';\nimport { type CliConfig, ensureNodeConfigFile } from './config.js';\nimport { printJsonError, printJsonEvent } from './format.js';\nimport { appendToTodayLog, resolveLogDirForDate } from './log-files.js';\nimport { runMigrationGuard } from './node-migration.js';\nimport {\n getBinaryVersion,\n startRuntimeDaemonFromNode,\n stopRuntimeDaemonFromNode,\n} from './node-runtime-daemon.js';\nimport { isProcessRunning, readPidFile, removePidFile, writePidFile } from './pid.js';\nimport { createRpcClient } from './rpc.js';\nimport { removeRuntimeFiles, writeRuntimeMeta, writeRuntimePid } from './runtime-meta.js';\nimport {\n findListeningProcessByPort,\n isFiberRuntimeCommand,\n terminateProcess,\n} from './runtime-port.js';\n\nexport interface NodeStartOptions {\n daemon?: boolean;\n runtimeProxyListen?: string;\n eventStream?: string;\n quietFnn?: boolean;\n json?: boolean;\n}\n\nexport async function runNodeStartCommand(\n config: CliConfig,\n options: NodeStartOptions,\n): Promise<void> {\n const json = Boolean(options.json);\n const daemon = Boolean(options.daemon);\n const isNodeChild = process.env.FIBER_NODE_CHILD === '1';\n const quietFnn = Boolean(options.quietFnn);\n const eventStream = String(options.eventStream ?? 'jsonl').toLowerCase();\n const emitStage = (stage: string, status: 'ok' | 'error', data: Record<string, unknown>) => {\n if (!json) return;\n printJsonEvent('startup_stage', { stage, status, ...data });\n };\n const emitFnnLog = (stream: 'stdout' | 'stderr', text: string) => {\n if (quietFnn) {\n return;\n }\n\n if (json) {\n printJsonEvent('fnn_log', { stream, text });\n return;\n }\n\n const target = stream === 'stderr' ? process.stderr : process.stdout;\n const payload = text.endsWith('\\n') ? text : `${text}\\n`;\n target.write(`[fnn:${stream}] ${payload}`);\n };\n if (json && eventStream !== 'jsonl') {\n printJsonError({\n code: 'NODE_EVENT_STREAM_INVALID',\n message: `Unsupported --event-stream format: ${options.eventStream}. Expected: jsonl`,\n recoverable: true,\n suggestion: 'Use `--event-stream jsonl` when using --json.',\n details: { provided: options.eventStream, expected: ['jsonl'] },\n });\n process.exit(1);\n }\n\n if (daemon && !isNodeChild) {\n const cliEntrypoint = process.argv[1];\n if (!cliEntrypoint) {\n const message = 'Unable to resolve CLI entrypoint path for --daemon mode';\n if (json) {\n printJsonError({\n code: 'NODE_DAEMON_START_FAILED',\n message,\n recoverable: true,\n suggestion: 'Retry without --daemon or check CLI invocation method.',\n });\n } else {\n console.error(`❌ ${message}`);\n }\n process.exit(1);\n }\n\n const childArgs = process.argv.slice(2).filter((arg) => arg !== '--daemon');\n const child = spawn(process.execPath, [cliEntrypoint, ...childArgs], {\n detached: true,\n stdio: 'ignore',\n cwd: process.cwd(),\n env: {\n ...process.env,\n FIBER_NODE_CHILD: '1',\n FIBER_NODE_RUNTIME_DAEMON: '1',\n },\n });\n child.unref();\n\n const childPid = child.pid;\n if (!childPid) {\n const message = 'Failed to spawn node daemon process';\n if (json) {\n printJsonError({\n code: 'NODE_DAEMON_START_FAILED',\n message,\n recoverable: true,\n suggestion: 'Retry node start and inspect system process limits.',\n });\n } else {\n console.error(`❌ ${message}`);\n }\n process.exit(1);\n }\n\n if (json) {\n printJsonEvent('node_daemon_starting', {\n pid: childPid,\n runtimeDaemon: true,\n });\n } else {\n console.log(`Node daemon starting (PID: ${childPid})`);\n console.log('Use `fiber-pay node status --json` to verify readiness.');\n }\n return;\n }\n\n emitStage('init', 'ok', { rpcUrl: config.rpcUrl, dataDir: config.dataDir });\n const existingPid = readPidFile(config.dataDir);\n if (existingPid && isProcessRunning(existingPid)) {\n if (json) {\n printJsonError({\n code: 'NODE_ALREADY_RUNNING',\n message: `Node is already running (PID: ${existingPid})`,\n recoverable: true,\n suggestion: 'Skip start or run `fiber-pay node stop` before retrying.',\n details: { pid: existingPid },\n });\n } else {\n console.log(`❌ Node is already running (PID: ${existingPid})`);\n }\n process.exit(1);\n }\n\n const runtimeDaemon = process.env.FIBER_NODE_RUNTIME_DAEMON === '1';\n const runtimeProxyListen = String(\n options.runtimeProxyListen ?? config.runtimeProxyListen ?? '127.0.0.1:8229',\n );\n const proxyListenSource: 'cli' | 'profile' | 'default' = options.runtimeProxyListen\n ? 'cli'\n : config.runtimeProxyListen\n ? 'profile'\n : 'default';\n const runtimeStateFilePath = join(config.dataDir, 'runtime-state.json');\n const logsBaseDir = join(config.dataDir, 'logs');\n mkdirSync(logsBaseDir, { recursive: true });\n // Ensure today's date directory exists at startup\n resolveLogDirForDate(config.dataDir);\n\n const resolvedBinary = resolveBinaryPath(config);\n const binaryPath = resolvedBinary.binaryPath;\n if (resolvedBinary.source === 'profile-managed') {\n const installDir = getBinaryManagerInstallDirOrThrow(resolvedBinary);\n await ensureFiberBinary({ installDir });\n }\n const binaryVersion = getBinaryVersion(binaryPath);\n const configFilePath = ensureNodeConfigFile(config.dataDir, config.network);\n emitStage('binary_resolved', 'ok', {\n binaryPath,\n binaryVersion,\n binarySource: resolvedBinary.source,\n configFilePath,\n });\n\n if (!json) {\n console.log(`🧩 Binary: ${binaryPath}`);\n console.log(`🧩 Version: ${binaryVersion}`);\n }\n\n // Check if database migration is needed before starting the node\n const guardResult = await runMigrationGuard({ dataDir: config.dataDir, binaryPath, json });\n if (guardResult.checked) {\n emitStage('migration_check', 'ok', {\n storePath: `${config.dataDir}/store`,\n needed: false,\n });\n } else {\n emitStage('migration_check', 'ok', {\n storePath: `${config.dataDir}/store`,\n skipped: true,\n reason: guardResult.skippedReason,\n });\n }\n\n const nodeConfig: FiberNodeConfig = {\n binaryPath,\n dataDir: config.dataDir,\n configFilePath,\n chain: config.network,\n keyPassword: config.keyPassword,\n };\n\n try {\n const keyManager = createKeyManager(config.dataDir, {\n encryptionPassword: config.keyPassword,\n autoGenerate: true,\n });\n await keyManager.initialize();\n emitStage('key_initialized', 'ok', {});\n } catch (error) {\n const message = `Failed to initialize node keys: ${error instanceof Error ? error.message : String(error)}`;\n emitStage('key_initialized', 'error', { code: 'NODE_KEY_INIT_FAILED', message });\n if (json) {\n printJsonError({\n code: 'NODE_KEY_INIT_FAILED',\n message,\n recoverable: true,\n suggestion: 'Verify key password and write permission for the data directory.',\n details: { dataDir: config.dataDir },\n });\n } else {\n console.error(`❌ ${message}`);\n }\n process.exit(1);\n }\n\n const processManager = new ProcessManager(nodeConfig);\n let earlyStop: { code: number | null; signal: NodeJS.Signals | null } | null = null;\n const formatStopDetails = (\n stop: { code: number | null; signal: NodeJS.Signals | null } | null,\n ): string => {\n if (!stop) return '';\n return ` (code: ${stop.code ?? 'null'}, signal: ${stop.signal ?? 'null'})`;\n };\n processManager.on('stopped', (code, signal) => {\n earlyStop = { code, signal };\n removePidFile(config.dataDir);\n });\n processManager.on('stdout', (text) => {\n appendToTodayLog(config.dataDir, 'fnn.stdout.log', text);\n emitFnnLog('stdout', text);\n });\n processManager.on('stderr', (text) => {\n appendToTodayLog(config.dataDir, 'fnn.stderr.log', text);\n emitFnnLog('stderr', text);\n });\n await processManager.start();\n const processManagerState = processManager as unknown as {\n process?: { pid?: number };\n };\n const processId = processManagerState.process?.pid;\n if (processId !== undefined) {\n writePidFile(config.dataDir, processId);\n }\n emitStage('process_started', 'ok', { pid: processId ?? null });\n\n let runtime: Awaited<ReturnType<typeof startRuntimeService>> | undefined;\n\n const rpc = createRpcClient(config);\n let rpcReady = true;\n try {\n await rpc.waitForReady({ timeout: 30000, interval: 500 });\n } catch {\n rpcReady = false;\n }\n\n if (earlyStop || processManager.getState() === 'stopped') {\n const details = formatStopDetails(earlyStop);\n emitStage('process_started', 'error', {\n code: 'NODE_STARTUP_EXITED',\n details,\n });\n if (json) {\n printJsonError({\n code: 'NODE_STARTUP_EXITED',\n message: `Fiber node exited during startup${details}`,\n recoverable: true,\n suggestion: 'Inspect fnn logs and verify config ports are free before retrying.',\n details: earlyStop ?? undefined,\n });\n } else {\n console.error(`❌ Fiber node exited during startup${details}`);\n }\n removePidFile(config.dataDir);\n if (runtimeDaemon) {\n stopRuntimeDaemonFromNode({ dataDir: config.dataDir, rpcUrl: config.rpcUrl });\n } else if (runtime) {\n await runtime.stop().catch(() => undefined);\n }\n removeRuntimeFiles(config.dataDir);\n process.exit(1);\n }\n\n try {\n const runtimePortProcess = findListeningProcessByPort(runtimeProxyListen);\n if (runtimePortProcess) {\n if (isFiberRuntimeCommand(runtimePortProcess.command)) {\n const terminated = await terminateProcess(runtimePortProcess.pid);\n if (!terminated) {\n throw new Error(\n `Runtime proxy ${runtimeProxyListen} is occupied by stale fiber-pay runtime PID ${runtimePortProcess.pid}, but termination failed`,\n );\n }\n removeRuntimeFiles(config.dataDir);\n emitStage('runtime_preflight', 'ok', {\n proxyListen: runtimeProxyListen,\n cleanedStaleProcessPid: runtimePortProcess.pid,\n });\n } else if (runtimePortProcess.command) {\n const details = runtimePortProcess.command\n ? `PID ${runtimePortProcess.pid} (${runtimePortProcess.command})`\n : `PID ${runtimePortProcess.pid}`;\n throw new Error(\n `Runtime proxy ${runtimeProxyListen} is already in use by non-fiber-pay process: ${details}`,\n );\n } else {\n throw new Error(\n `Runtime proxy ${runtimeProxyListen} is already in use by process PID ${runtimePortProcess.pid}. ` +\n 'Unable to determine command owner; inspect this PID manually before retrying.',\n );\n }\n }\n\n if (runtimeDaemon) {\n const daemonStart = startRuntimeDaemonFromNode({\n dataDir: config.dataDir,\n rpcUrl: config.rpcUrl,\n proxyListen: runtimeProxyListen,\n stateFilePath: runtimeStateFilePath,\n alertLogsBaseDir: logsBaseDir,\n });\n if (!daemonStart.ok) {\n throw new Error(daemonStart.message);\n }\n } else {\n runtime = await startRuntimeService({\n fiberRpcUrl: config.rpcUrl,\n proxy: {\n enabled: true,\n listen: runtimeProxyListen,\n },\n storage: {\n stateFilePath: runtimeStateFilePath,\n },\n alerts: [{ type: 'stdout' }, { type: 'daily-file', baseLogsDir: logsBaseDir }],\n jobs: {\n enabled: true,\n dbPath: join(config.dataDir, 'runtime-jobs.db'),\n },\n });\n\n const runtimeStatus = runtime.service.getStatus();\n writeRuntimePid(config.dataDir, process.pid);\n const todayLogDir = resolveLogDirForDate(config.dataDir);\n writeRuntimeMeta(config.dataDir, {\n pid: process.pid,\n startedAt: runtimeStatus.startedAt,\n fiberRpcUrl: runtimeStatus.targetUrl,\n proxyListen: runtimeStatus.proxyListen,\n stateFilePath: runtimeStateFilePath,\n alertLogFilePath: join(todayLogDir, 'runtime.alerts.jsonl'),\n fnnStdoutLogPath: join(todayLogDir, 'fnn.stdout.log'),\n fnnStderrLogPath: join(todayLogDir, 'fnn.stderr.log'),\n logsBaseDir,\n daemon: false,\n });\n }\n\n emitStage('runtime_started', 'ok', {\n proxyListen: runtimeProxyListen,\n daemon: runtimeDaemon,\n });\n } catch (error) {\n const message = `Runtime failed to start: ${error instanceof Error ? error.message : String(error)}`;\n emitStage('runtime_started', 'error', {\n code: 'NODE_RUNTIME_START_FAILED',\n message,\n proxyListen: runtimeProxyListen,\n });\n if (json) {\n printJsonError({\n code: 'NODE_RUNTIME_START_FAILED',\n message,\n recoverable: true,\n suggestion: 'Retry with a free --runtime-proxy-listen port.',\n details: {\n runtimeProxyListen,\n },\n });\n } else {\n console.error(`❌ ${message}`);\n }\n\n removeRuntimeFiles(config.dataDir);\n removePidFile(config.dataDir);\n await processManager.stop().catch(() => undefined);\n process.exit(1);\n }\n\n if (!rpcReady) {\n emitStage('rpc_ready', 'error', {\n code: 'NODE_RPC_NOT_READY',\n timeoutSeconds: 30,\n });\n if (json) {\n printJsonError({\n code: 'NODE_RPC_NOT_READY',\n message: 'RPC did not become ready within 30s. Node startup failed.',\n recoverable: true,\n suggestion: 'Retry after a delay and verify RPC port + config consistency.',\n details: { timeoutSeconds: 30, rpcUrl: config.rpcUrl },\n });\n } else {\n console.error('❌ RPC did not become ready within 30s. Node startup failed.');\n }\n const stderrTail = processManager.getStderr(12).join('').trim();\n const stdoutTail = processManager.getStdout(12).join('').trim();\n if (!json && stderrTail.length > 0) {\n console.error('--- fnn stderr (tail) ---');\n console.error(stderrTail);\n }\n if (!json && stdoutTail.length > 0) {\n console.error('--- fnn stdout (tail) ---');\n console.error(stdoutTail);\n }\n\n removePidFile(config.dataDir);\n if (runtimeDaemon) {\n stopRuntimeDaemonFromNode({ dataDir: config.dataDir, rpcUrl: config.rpcUrl });\n } else if (runtime) {\n await runtime.stop().catch(() => undefined);\n removeRuntimeFiles(config.dataDir);\n }\n await processManager.stop().catch(() => undefined);\n process.exit(1);\n }\n emitStage('rpc_ready', 'ok', { rpcUrl: config.rpcUrl });\n\n const bootnodes = nodeConfig.configFilePath\n ? extractBootnodeAddrs(nodeConfig.configFilePath)\n : extractBootnodeAddrs(join(config.dataDir, 'config.yml'));\n if (bootnodes.length > 0) {\n await autoConnectBootnodes(rpc, bootnodes);\n }\n emitStage('bootnodes_connected', 'ok', { count: bootnodes.length });\n\n if (earlyStop || processManager.getState() === 'stopped') {\n const details = formatStopDetails(earlyStop);\n emitStage('bootnodes_connected', 'error', {\n code: 'NODE_STARTUP_EXITED',\n details,\n });\n if (json) {\n printJsonError({\n code: 'NODE_STARTUP_EXITED',\n message: `Fiber node exited during startup${details}`,\n recoverable: true,\n suggestion: 'Inspect fnn logs and verify config ports are free before retrying.',\n details: earlyStop ?? undefined,\n });\n } else {\n console.error(`❌ Fiber node exited during startup${details}`);\n }\n removePidFile(config.dataDir);\n process.exit(1);\n }\n\n if (json) {\n emitStage('startup_complete', 'ok', {\n pid: processId ?? null,\n rpcUrl: config.rpcUrl,\n });\n printJsonEvent('node_started', {\n rpcUrl: config.rpcUrl,\n binaryPath,\n binaryVersion,\n pid: processId ?? null,\n runtimeEnabled: true,\n runtimeDaemon,\n quietFnn,\n proxyUrl: `http://${runtimeProxyListen}`,\n proxyListenSource,\n logs: {\n baseDir: logsBaseDir,\n todayDir: resolveLogDirForDate(config.dataDir),\n },\n });\n } else {\n console.log('✅ Fiber node started successfully!');\n console.log(` RPC endpoint: ${config.rpcUrl}`);\n console.log(\n ` Runtime proxy: http://${runtimeProxyListen} (browser-safe endpoint + monitoring)`,\n );\n console.log(` Runtime mode: ${runtimeDaemon ? 'daemon' : 'embedded'}`);\n console.log(` Log files: ${logsBaseDir}`);\n console.log(' Press Ctrl+C to stop.');\n }\n\n let shutdownRequested = false;\n const shutdown = async () => {\n if (shutdownRequested) return;\n shutdownRequested = true;\n if (!json) {\n console.log('\\n🛑 Shutting down...');\n }\n if (runtimeDaemon) {\n stopRuntimeDaemonFromNode({ dataDir: config.dataDir, rpcUrl: config.rpcUrl });\n } else if (runtime) {\n await runtime.stop();\n }\n removeRuntimeFiles(config.dataDir);\n removePidFile(config.dataDir);\n await processManager.stop();\n if (json) {\n printJsonEvent('node_stopped', { reason: 'signal' });\n } else {\n console.log('✅ Node stopped.');\n }\n };\n\n await new Promise<void>((resolve) => {\n const keepAlive = setInterval(() => undefined, 60_000);\n\n const cleanup = () => {\n clearInterval(keepAlive);\n process.off('SIGINT', onSigInt);\n process.off('SIGTERM', onSigTerm);\n processManager.off('stopped', onStopped);\n resolve();\n };\n\n const onStopped = () => {\n cleanup();\n };\n\n const onSigInt = () => {\n shutdown().finally(cleanup);\n };\n\n const onSigTerm = () => {\n shutdown().finally(cleanup);\n };\n\n process.on('SIGINT', onSigInt);\n process.on('SIGTERM', onSigTerm);\n processManager.on('stopped', onStopped);\n });\n\n if (!shutdownRequested) {\n if (json) {\n printJsonError({\n code: 'NODE_STOPPED_UNEXPECTEDLY',\n message: 'Fiber node stopped unexpectedly.',\n recoverable: true,\n suggestion: 'Check process logs and restart the node when configuration is healthy.',\n });\n } else {\n console.error('❌ Fiber node stopped unexpectedly.');\n }\n removePidFile(config.dataDir);\n if (runtimeDaemon) {\n stopRuntimeDaemonFromNode({ dataDir: config.dataDir, rpcUrl: config.rpcUrl });\n }\n removeRuntimeFiles(config.dataDir);\n process.exit(1);\n }\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport type { FiberRpcClient } from '@fiber-pay/sdk';\nimport { parse as parseYaml } from 'yaml';\n\nexport function extractBootnodeAddrs(configFilePath: string): string[] {\n if (!existsSync(configFilePath)) return [];\n\n try {\n const content = readFileSync(configFilePath, 'utf-8');\n const doc = parseYaml(content);\n const addrs = doc?.fiber?.bootnode_addrs;\n if (!Array.isArray(addrs)) return [];\n return addrs.filter((a): a is string => typeof a === 'string' && a.startsWith('/ip'));\n } catch {\n return [];\n }\n}\n\nexport async function autoConnectBootnodes(\n rpc: FiberRpcClient,\n bootnodes: string[],\n): Promise<void> {\n if (bootnodes.length === 0) return;\n\n console.log(`🔗 Connecting to ${bootnodes.length} bootnode(s)...`);\n for (const addr of bootnodes) {\n const shortId = addr.match(/\\/p2p\\/(.+)$/)?.[1]?.slice(0, 12) || addr.slice(-12);\n try {\n await rpc.connectPeer({ address: addr });\n console.log(` ✅ Connected to ${shortId}...`);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n if (msg.toLowerCase().includes('already')) {\n console.log(` ✅ Already connected to ${shortId}...`);\n } else {\n console.error(` ⚠️ Failed to connect to ${shortId}...: ${msg}`);\n }\n }\n }\n}\n","/**\n * Shared migration-guard logic used by both `node start` and `node upgrade`.\n */\n\nimport { dirname } from 'node:path';\nimport { BinaryManager, type MigrationCheckResult, MigrationManager } from '@fiber-pay/node';\nimport { printJsonError } from './format.js';\nimport { replaceRawMigrateHint } from './migration-utils.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface MigrationGuardResult {\n /** Whether the guard ran (false when no store exists or fnn-migrate is missing) */\n checked: boolean;\n /** The migration check result (undefined when `checked` is false) */\n migrationCheck?: MigrationCheckResult;\n /** When the guard was skipped, explain why */\n skippedReason?: string;\n}\n\nexport interface MigrationGuardOptions {\n /** Absolute data directory */\n dataDir: string;\n /**\n * Resolved binary path of `fnn`.\n * The migrate binary is looked up relative to the *directory* of this path,\n * so it works even when binaryPath is overridden via config.\n */\n binaryPath: string;\n /** Output machine-readable JSON instead of human-friendly text */\n json: boolean;\n}\n\n// =============================================================================\n// Pre-start migration guard\n// =============================================================================\n\n/**\n * Check whether the on-disk store requires migration before starting fnn.\n *\n * - If migration is needed the function prints an error and calls\n * `process.exit(1)`.\n * - If `fnn-migrate` is unavailable the check is silently skipped (the node\n * itself will fail later with a clear error if the schema really is stale).\n * - Returns a result describing what happened so callers can emit structured\n * events (e.g. startup stages).\n */\nexport async function runMigrationGuard(\n opts: MigrationGuardOptions,\n): Promise<MigrationGuardResult> {\n const { dataDir, binaryPath, json } = opts;\n\n if (!MigrationManager.storeExists(dataDir)) {\n return { checked: false, skippedReason: 'store does not exist' };\n }\n\n const storePath = MigrationManager.resolveStorePath(dataDir);\n const binaryDir = dirname(binaryPath);\n const bm = new BinaryManager(binaryDir);\n const migrateBinPath = bm.getMigrateBinaryPath();\n\n let migrationCheck: MigrationCheckResult;\n try {\n const migrationManager = new MigrationManager(migrateBinPath);\n migrationCheck = await migrationManager.check(storePath);\n } catch {\n // fnn-migrate binary may not exist (e.g. older install). Skip silently.\n return { checked: false, skippedReason: 'fnn-migrate binary not available' };\n }\n\n if (migrationCheck.needed) {\n const message = migrationCheck.valid\n ? 'Database migration required. Run `fiber-pay node upgrade --force-migrate` before starting.'\n : replaceRawMigrateHint(migrationCheck.message);\n\n if (json) {\n printJsonError({\n code: 'MIGRATION_REQUIRED',\n message,\n recoverable: true,\n suggestion: `Back up your store first (directory: \"${storePath}\"). Then run \\`fiber-pay node upgrade --force-migrate\\`. If migration still fails, close channels on the old fnn version, remove the store, and restart with a fresh store. If backup exists, restore it to roll back.`,\n details: {\n storePath,\n migrationCheck: {\n ...migrationCheck,\n message,\n },\n },\n });\n } else {\n console.error(`❌ ${message}`);\n console.error(` 1) Back up store directory: ${storePath}`);\n console.error(' 2) Run: fiber-pay node upgrade --force-migrate');\n console.error(\n ' 3) If it still fails, close channels on old fnn, remove store, then restart.',\n );\n console.error(' 4) If backup exists, restore it to roll back.');\n }\n process.exit(1);\n }\n\n return { checked: true, migrationCheck };\n}\n","export function replaceRawMigrateHint(message: string): string {\n return message.replace(\n /Fiber need to run some database migrations, please run `fnn-migrate[^`]*` to start migrations\\.?/g,\n 'Fiber database migration is required.',\n );\n}\n\nexport function normalizeMigrationCheck<T extends { message: string }>(check: T): T {\n return {\n ...check,\n message: replaceRawMigrateHint(check.message),\n };\n}\n","import { spawnSync } from 'node:child_process';\nimport { isProcessRunning } from './pid.js';\n\nexport interface PortProcessInfo {\n pid: number;\n command?: string;\n}\n\nexport function parsePortFromListen(listen: string): number | undefined {\n const value = listen.trim();\n if (!value) {\n return undefined;\n }\n\n const lastColon = value.lastIndexOf(':');\n if (lastColon < 0 || lastColon === value.length - 1) {\n return undefined;\n }\n\n const port = Number(value.slice(lastColon + 1));\n if (!Number.isInteger(port) || port < 1 || port > 65535) {\n return undefined;\n }\n return port;\n}\n\nexport function extractFirstPidFromLsofOutput(output: string): number | undefined {\n for (const line of output.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed.startsWith('p') || trimmed.length < 2) {\n continue;\n }\n const pid = Number(trimmed.slice(1));\n if (Number.isInteger(pid) && pid > 0) {\n return pid;\n }\n }\n return undefined;\n}\n\nexport function readProcessCommand(pid: number): string | undefined {\n const result = spawnSync('ps', ['-p', String(pid), '-o', 'command='], {\n encoding: 'utf-8',\n });\n if (result.error || result.status !== 0) {\n return undefined;\n }\n const command = (result.stdout ?? '').trim();\n return command.length > 0 ? command : undefined;\n}\n\nexport function findListeningProcessByPort(listen: string): PortProcessInfo | undefined {\n const port = parsePortFromListen(listen);\n if (!port) {\n return undefined;\n }\n\n const result = spawnSync('lsof', ['-nP', `-iTCP:${port}`, '-sTCP:LISTEN', '-Fp'], {\n encoding: 'utf-8',\n });\n if (result.error || result.status !== 0) {\n return undefined;\n }\n\n const pid = extractFirstPidFromLsofOutput(result.stdout ?? '');\n if (!pid) {\n return undefined;\n }\n\n return {\n pid,\n command: readProcessCommand(pid),\n };\n}\n\nexport function isFiberRuntimeCommand(command: string | undefined): boolean {\n if (!command) {\n return false;\n }\n\n const normalized = command.toLowerCase();\n const hasFiberIdentifier =\n normalized.includes('fiber-pay') ||\n normalized.includes('@fiber-pay/cli') ||\n normalized.includes('/packages/cli/dist/cli.js') ||\n normalized.includes('\\\\packages\\\\cli\\\\dist\\\\cli.js') ||\n normalized.includes('/dist/cli.js') ||\n normalized.includes('\\\\dist\\\\cli.js');\n\n if (!hasFiberIdentifier) {\n return false;\n }\n\n return normalized.includes('runtime') && normalized.includes('start');\n}\n\nexport async function terminateProcess(pid: number, timeoutMs = 5_000): Promise<boolean> {\n if (!isProcessRunning(pid)) {\n return true;\n }\n\n try {\n process.kill(pid, 'SIGTERM');\n } catch (error) {\n if ((error as { code?: string }).code === 'ESRCH') {\n return true;\n }\n return false;\n }\n\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n if (!isProcessRunning(pid)) {\n return true;\n }\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n\n if (!isProcessRunning(pid)) {\n return true;\n }\n\n try {\n process.kill(pid, 'SIGKILL');\n } catch (error) {\n if ((error as { code?: string }).code === 'ESRCH') {\n return true;\n }\n return false;\n }\n\n const killDeadline = Date.now() + 1_000;\n while (Date.now() < killDeadline) {\n if (!isProcessRunning(pid)) {\n return true;\n }\n await new Promise((resolve) => setTimeout(resolve, 50));\n }\n\n return !isProcessRunning(pid);\n}\n","import { existsSync } from 'node:fs';\nimport {\n buildMultiaddrFromNodeId,\n buildMultiaddrFromRpcUrl,\n ChannelState,\n nodeIdToPeerId,\n type Script,\n scriptToAddress,\n} from '@fiber-pay/sdk';\nimport { getBinaryDetails } from './binary-path.js';\nimport type { CliConfig } from './config.js';\nimport { printJsonSuccess, sanitizeForTerminal } from './format.js';\nimport {\n buildReadyRecommendation,\n buildStalePidRecommendation,\n buildStatusRecommendation,\n summarizeChannelLiquidity,\n} from './node-recommendation.js';\nimport { getLockBalanceShannons } from './node-rpc.js';\nimport { isProcessRunning, readPidFile, removePidFile } from './pid.js';\nimport { createReadyRpcClient, resolveRpcEndpoint } from './rpc.js';\n\nexport interface NodeStatusOptions {\n json?: boolean;\n}\n\nexport async function runNodeStatusCommand(\n config: CliConfig,\n options: NodeStatusOptions,\n): Promise<void> {\n const json = Boolean(options.json);\n const pid = readPidFile(config.dataDir);\n const resolvedRpc = resolveRpcEndpoint(config);\n const { resolvedBinary, info: binaryInfo } = await getBinaryDetails(config);\n const configExists = existsSync(config.configPath);\n const nodeRunning = Boolean(pid && isProcessRunning(pid));\n\n let rpcResponsive = false;\n let nodeId: string | null = null;\n let nodeName: string | null = null;\n let addresses: string[] = [];\n let chainHash: string | null = null;\n let version: string | null = null;\n let peerId: string | null = null;\n let peersCount = 0;\n let peerIdError: string | null = null;\n let multiaddr: string | null = null;\n let multiaddrError: string | null = null;\n let multiaddrInferred = false;\n let channelsTotal = 0;\n let channelsReady = 0;\n let pendingChannelCount = 0;\n let canSend = false;\n let canReceive = false;\n let localCkb = 0;\n let remoteCkb = 0;\n let fundingAddress: string | null = null;\n let fundingLockScript: Script | null = null;\n let fundingCkb = 0;\n let fundingBalanceError: string | null = null;\n\n if (nodeRunning) {\n try {\n const rpc = await createReadyRpcClient(config);\n const nodeInfo = await rpc.nodeInfo();\n const channels = await rpc.listChannels({ include_closed: false });\n rpcResponsive = true;\n\n nodeId = nodeInfo.node_id;\n nodeName = nodeInfo.node_name;\n addresses = nodeInfo.addresses;\n chainHash = nodeInfo.chain_hash;\n version = nodeInfo.version;\n peersCount = parseInt(nodeInfo.peers_count, 16);\n try {\n peerId = await nodeIdToPeerId(nodeInfo.node_id);\n } catch (error) {\n peerIdError = error instanceof Error ? error.message : String(error);\n }\n\n const baseAddress = nodeInfo.addresses[0];\n if (baseAddress) {\n try {\n multiaddr = await buildMultiaddrFromNodeId(baseAddress, nodeInfo.node_id);\n } catch (error) {\n multiaddrError = error instanceof Error ? error.message : String(error);\n }\n } else if (peerId) {\n try {\n multiaddr = buildMultiaddrFromRpcUrl(config.rpcUrl, peerId);\n multiaddrInferred = true;\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n multiaddrError = `no advertised addresses; infer failed: ${reason}`;\n }\n }\n\n channelsTotal = channels.channels.length;\n const readyChannels = channels.channels.filter(\n (channel) => channel.state?.state_name === ChannelState.ChannelReady,\n );\n channelsReady = readyChannels.length;\n pendingChannelCount = Math.max(channelsTotal - channelsReady, 0);\n const liquidity = summarizeChannelLiquidity(readyChannels);\n canSend = liquidity.canSend;\n canReceive = liquidity.canReceive;\n localCkb = liquidity.localCkb;\n remoteCkb = liquidity.remoteCkb;\n\n fundingAddress = scriptToAddress(nodeInfo.default_funding_lock_script, config.network);\n fundingLockScript = nodeInfo.default_funding_lock_script as Script;\n if (config.ckbRpcUrl) {\n try {\n const fundingBalance = await getLockBalanceShannons(config.ckbRpcUrl, fundingLockScript);\n fundingCkb = Number(fundingBalance) / 1e8;\n } catch (error) {\n fundingBalanceError =\n error instanceof Error\n ? error.message\n : 'Failed to query CKB balance for funding address';\n }\n } else {\n fundingBalanceError =\n 'CKB RPC URL not configured (set ckb.rpc_url in config.yml or FIBER_CKB_RPC_URL)';\n }\n } catch {\n rpcResponsive = false;\n }\n } else if (pid) {\n removePidFile(config.dataDir);\n }\n\n const { recommendation, reasons } = buildStatusRecommendation({\n binaryReady: binaryInfo.ready,\n configExists,\n nodeRunning,\n rpcResponsive,\n channelsReady,\n canSend,\n canReceive,\n });\n\n const output = {\n running: nodeRunning,\n pid: pid ?? null,\n rpcResponsive,\n rpcUrl: config.rpcUrl,\n rpcTarget: resolvedRpc.target,\n resolvedRpcUrl: resolvedRpc.url,\n nodeId,\n nodeName,\n addresses,\n chainHash,\n version,\n peerId,\n peersCount,\n peerIdError,\n multiaddr,\n multiaddrError,\n multiaddrInferred,\n fundingLockScript,\n checks: {\n binary: {\n path: binaryInfo.path,\n ready: binaryInfo.ready,\n version: binaryInfo.version,\n source: resolvedBinary.source,\n managedPath: resolvedBinary.managedPath,\n resolvedPath: resolvedBinary.binaryPath,\n },\n config: {\n path: config.configPath,\n exists: configExists,\n network: config.network,\n rpcUrl: config.rpcUrl,\n },\n node: {\n running: nodeRunning,\n pid: pid ?? null,\n rpcReachable: rpcResponsive,\n rpcTarget: resolvedRpc.target,\n rpcClientUrl: resolvedRpc.url,\n },\n channels: {\n total: channelsTotal,\n ready: channelsReady,\n pending: pendingChannelCount,\n canSend,\n canReceive,\n },\n },\n balance: {\n totalCkb: localCkb + fundingCkb,\n channelLocalCkb: localCkb,\n availableToSend: localCkb,\n availableToReceive: remoteCkb,\n channelCount: channelsTotal,\n activeChannelCount: channelsReady,\n fundingAddress,\n fundingAddressTotalCkb: fundingCkb,\n fundingBalanceError,\n },\n recommendation,\n reasons,\n };\n\n if (json) {\n printJsonSuccess(output);\n return;\n }\n\n if (output.running) {\n console.log(`✅ Node is running (PID: ${output.pid})`);\n if (output.rpcResponsive) {\n console.log(` Node ID: ${String(output.nodeId)}`);\n if (output.nodeName) {\n console.log(` Name: ${sanitizeForTerminal(output.nodeName)}`);\n }\n if (output.version) {\n console.log(` Version: ${sanitizeForTerminal(output.version)}`);\n }\n if (output.chainHash) {\n console.log(` Chain Hash: ${String(output.chainHash)}`);\n }\n if (output.peerId) {\n console.log(` Peer ID: ${String(output.peerId)}`);\n } else if (output.peerIdError) {\n console.log(` Peer ID: unavailable (${String(output.peerIdError)})`);\n }\n console.log(` RPC: ${String(output.rpcUrl)}`);\n console.log(` RPC Client: ${String(output.rpcTarget)} (${String(output.resolvedRpcUrl)})`);\n if (output.multiaddr) {\n const inferredSuffix = output.multiaddrInferred\n ? ' (inferred from RPC + peerId; no advertised addresses)'\n : '';\n console.log(` Multiaddr: ${String(output.multiaddr)}${inferredSuffix}`);\n } else if (output.multiaddrError) {\n console.log(` Multiaddr: unavailable (${String(output.multiaddrError)})`);\n } else {\n console.log(' Multiaddr: unavailable');\n }\n if (output.addresses.length > 0) {\n console.log(' Addresses:');\n for (const address of output.addresses) {\n console.log(` - ${sanitizeForTerminal(address)}`);\n }\n }\n } else {\n console.log(' ⚠️ RPC not responding');\n }\n } else if (output.pid) {\n console.log(`❌ Node is not running (stale PID file: ${output.pid})`);\n } else {\n console.log('❌ Node is not running');\n }\n\n console.log('');\n console.log('Diagnostics');\n console.log(` Binary: ${output.checks.binary.ready ? 'ready' : 'missing'}`);\n console.log(` Binary Path: ${output.checks.binary.resolvedPath}`);\n console.log(` Config: ${output.checks.config.exists ? 'present' : 'missing'}`);\n console.log(` RPC: ${output.checks.node.rpcReachable ? 'reachable' : 'unreachable'}`);\n console.log(\n ` Channels: ${output.checks.channels.ready}/${output.checks.channels.pending}/${output.checks.channels.total} ready/pending/total`,\n );\n if (output.rpcResponsive) {\n console.log(` Peers: ${output.peersCount}`);\n } else {\n console.log(' Peers: unavailable');\n }\n console.log(` Can Send: ${output.checks.channels.canSend ? 'yes' : 'no'}`);\n console.log(` Can Receive: ${output.checks.channels.canReceive ? 'yes' : 'no'}`);\n console.log(` Recommendation:${output.recommendation}`);\n if (output.reasons.length > 0) {\n console.log(' Reasons:');\n for (const reason of output.reasons) {\n console.log(` - ${reason}`);\n }\n }\n\n console.log('');\n console.log('Balance');\n console.log(` Total CKB: ${output.balance.totalCkb.toFixed(8)}`);\n console.log(` Channel Local: ${output.balance.channelLocalCkb.toFixed(8)}`);\n console.log(` To Send: ${output.balance.availableToSend.toFixed(8)}`);\n console.log(` To Receive: ${output.balance.availableToReceive.toFixed(8)}`);\n console.log(\n ` Channels: ${output.balance.activeChannelCount}/${output.balance.channelCount} active/total`,\n );\n if (output.balance.fundingAddress) {\n console.log(` Funding Addr: ${output.balance.fundingAddress}`);\n }\n console.log(` Funding CKB: ${output.balance.fundingAddressTotalCkb.toFixed(8)}`);\n if (output.balance.fundingBalanceError) {\n console.log(` Funding Err: ${output.balance.fundingBalanceError}`);\n }\n}\n\nexport async function runNodeReadyCommand(\n config: CliConfig,\n options: NodeStatusOptions,\n): Promise<void> {\n const json = Boolean(options.json);\n const pid = readPidFile(config.dataDir);\n const output: Record<string, unknown> = {\n nodeRunning: false,\n rpcReachable: false,\n channelsTotal: 0,\n channelsReady: 0,\n canSend: false,\n canReceive: false,\n recommendation: 'NODE_STOPPED',\n reasons: ['Node process is not running.'],\n pid: pid ?? null,\n rpcUrl: config.rpcUrl,\n };\n\n if (pid && isProcessRunning(pid)) {\n output.nodeRunning = true;\n output.reasons = [];\n\n try {\n const rpc = await createReadyRpcClient(config);\n output.rpcReachable = true;\n const channels = await rpc.listChannels({ include_closed: false });\n output.channelsTotal = channels.channels.length;\n\n const readyChannels = channels.channels.filter(\n (channel) => channel.state?.state_name === ChannelState.ChannelReady,\n );\n output.channelsReady = readyChannels.length;\n\n const liquidity = summarizeChannelLiquidity(readyChannels);\n output.canSend = liquidity.canSend;\n output.canReceive = liquidity.canReceive;\n\n const readyRecommendation = buildReadyRecommendation({\n nodeRunning: true,\n rpcReachable: true,\n channelsReady: readyChannels.length,\n canSend: liquidity.canSend,\n canReceive: liquidity.canReceive,\n });\n output.recommendation = readyRecommendation.recommendation;\n output.reasons = readyRecommendation.reasons;\n } catch {\n output.rpcReachable = false;\n const readyRecommendation = buildReadyRecommendation({\n nodeRunning: true,\n rpcReachable: false,\n channelsReady: 0,\n canSend: false,\n canReceive: false,\n });\n output.recommendation = readyRecommendation.recommendation;\n output.reasons = readyRecommendation.reasons;\n }\n } else if (pid) {\n const staleRecommendation = buildStalePidRecommendation();\n output.recommendation = staleRecommendation.recommendation;\n output.reasons = staleRecommendation.reasons;\n removePidFile(config.dataDir);\n }\n\n if (json) {\n printJsonSuccess(output);\n } else {\n console.log('Node Readiness');\n console.log(` Node Running: ${output.nodeRunning ? 'yes' : 'no'}`);\n console.log(` RPC Reachable: ${output.rpcReachable ? 'yes' : 'no'}`);\n console.log(` Channels: ${output.channelsReady}/${output.channelsTotal} ready/total`);\n console.log(` Can Send: ${output.canSend ? 'yes' : 'no'}`);\n console.log(` Can Receive: ${output.canReceive ? 'yes' : 'no'}`);\n console.log(` Recommendation: ${String(output.recommendation)}`);\n const reasons = Array.isArray(output.reasons) ? output.reasons : [];\n if (reasons.length > 0) {\n console.log(' Reasons:');\n for (const reason of reasons) {\n console.log(` - ${String(reason)}`);\n }\n }\n }\n}\n","type StatusRecommendationInput = {\n binaryReady: boolean;\n configExists: boolean;\n nodeRunning: boolean;\n rpcResponsive: boolean;\n channelsReady: number;\n canSend: boolean;\n canReceive: boolean;\n};\n\ntype ReadyRecommendationInput = {\n nodeRunning: boolean;\n rpcReachable: boolean;\n channelsReady: number;\n canSend: boolean;\n canReceive: boolean;\n};\n\ntype RecommendationResult = {\n recommendation: string;\n reasons: string[];\n};\n\nexport function summarizeChannelLiquidity(\n readyChannels: Array<{ local_balance: string; remote_balance: string }>,\n): { canSend: boolean; canReceive: boolean; localCkb: number; remoteCkb: number } {\n const canSend = readyChannels.some((channel) => BigInt(channel.local_balance) > 0n);\n const canReceive = readyChannels.some((channel) => BigInt(channel.remote_balance) > 0n);\n\n let totalLocal = 0n;\n let totalRemote = 0n;\n for (const channel of readyChannels) {\n totalLocal += BigInt(channel.local_balance);\n totalRemote += BigInt(channel.remote_balance);\n }\n\n return {\n canSend,\n canReceive,\n localCkb: Number(totalLocal) / 1e8,\n remoteCkb: Number(totalRemote) / 1e8,\n };\n}\n\nexport function buildStatusRecommendation(input: StatusRecommendationInput): RecommendationResult {\n const reasons: string[] = [];\n\n if (!input.binaryReady) reasons.push('Fiber binary is missing or not executable.');\n if (!input.configExists) reasons.push('Config file is missing.');\n if (!input.nodeRunning) reasons.push('Node process is not running.');\n if (input.nodeRunning && !input.rpcResponsive) {\n reasons.push('Node process is running but RPC is not reachable.');\n }\n if (input.rpcResponsive && input.channelsReady === 0) {\n reasons.push('No ChannelReady channel found.');\n }\n if (input.channelsReady > 0 && !input.canSend && input.canReceive) {\n reasons.push('Send liquidity is low on ChannelReady channels.');\n }\n if (input.channelsReady > 0 && input.canSend && !input.canReceive) {\n reasons.push('Receive liquidity is low on ChannelReady channels.');\n }\n if (input.channelsReady > 0 && !input.canSend && !input.canReceive) {\n reasons.push('ChannelReady channels exist but liquidity is zero.');\n }\n\n let recommendation = 'READY';\n if (!input.binaryReady) {\n recommendation = 'INSTALL_BINARY';\n } else if (!input.configExists) {\n recommendation = 'INIT_CONFIG';\n } else if (!input.nodeRunning) {\n recommendation = 'START_NODE';\n } else if (!input.rpcResponsive) {\n recommendation = 'WAIT_RPC';\n } else if (input.channelsReady === 0) {\n recommendation = 'OPEN_CHANNEL';\n } else if (!input.canSend && !input.canReceive) {\n recommendation = 'NO_LIQUIDITY';\n } else if (!input.canSend && input.canReceive) {\n recommendation = 'SEND_CAPACITY_LOW';\n } else if (input.canSend && !input.canReceive) {\n recommendation = 'RECEIVE_CAPACITY_LOW';\n }\n\n return { recommendation, reasons };\n}\n\nexport function buildReadyRecommendation(input: ReadyRecommendationInput): RecommendationResult {\n if (!input.nodeRunning) {\n return {\n recommendation: 'NODE_STOPPED',\n reasons: ['Node process is not running.'],\n };\n }\n\n if (!input.rpcReachable) {\n return {\n recommendation: 'RPC_UNREACHABLE',\n reasons: ['Node process is running but RPC is not reachable.'],\n };\n }\n\n if (input.channelsReady === 0) {\n return {\n recommendation: 'NEED_CHANNEL',\n reasons: ['No ChannelReady channel found. Open and wait for channel readiness.'],\n };\n }\n\n if (input.canSend && input.canReceive) {\n return {\n recommendation: 'READY',\n reasons: ['Node is reachable and has send/receive liquidity.'],\n };\n }\n\n if (input.canSend) {\n return {\n recommendation: 'RECEIVE_CAPACITY_LOW',\n reasons: ['Receive liquidity is low on all ChannelReady channels.'],\n };\n }\n\n if (input.canReceive) {\n return {\n recommendation: 'SEND_CAPACITY_LOW',\n reasons: ['Send liquidity is low on all ChannelReady channels.'],\n };\n }\n\n return {\n recommendation: 'NO_LIQUIDITY',\n reasons: ['ChannelReady channels exist but both local/remote liquidity are zero.'],\n };\n}\n\nexport function buildStalePidRecommendation(): RecommendationResult {\n return {\n recommendation: 'NODE_STOPPED',\n reasons: ['Stale PID file detected and cleaned.'],\n };\n}\n","import type { Script } from '@fiber-pay/sdk';\n\nconst CELLS_PAGE_SIZE = 100;\n\ninterface IndexerCellsResponse {\n objects: Array<{ output?: { capacity?: string } }>;\n last_cursor?: string;\n}\n\nexport async function callJsonRpc<TResult>(\n url: string,\n method: string,\n params: unknown[],\n): Promise<TResult> {\n const response = await fetch(url, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status} ${response.statusText}`);\n }\n\n const payload = (await response.json()) as {\n result?: TResult;\n error?: { message?: string; code?: number };\n };\n\n if (payload.error) {\n const code = payload.error.code ?? 'unknown';\n const message = payload.error.message ?? 'JSON-RPC error';\n throw new Error(`${message} (code: ${code})`);\n }\n\n if (payload.result === undefined) {\n throw new Error('Missing JSON-RPC result');\n }\n\n return payload.result;\n}\n\nexport async function getLockBalanceShannons(\n ckbRpcUrl: string,\n lockScript: Script,\n): Promise<bigint> {\n let cursor: string | undefined;\n let total = 0n;\n const limitHex = `0x${CELLS_PAGE_SIZE.toString(16)}`;\n\n for (let i = 0; i < 2000; i++) {\n const params: unknown[] = [{ script: lockScript, script_type: 'lock' }, 'asc', limitHex];\n if (cursor) {\n params.push(cursor);\n }\n\n const page = await callJsonRpc<IndexerCellsResponse>(ckbRpcUrl, 'get_cells', params);\n const cells = page.objects ?? [];\n\n for (const cell of cells) {\n if (cell.output?.capacity) {\n total += BigInt(cell.output.capacity);\n }\n }\n\n const nextCursor = page.last_cursor;\n if (!nextCursor || nextCursor === cursor || cells.length < CELLS_PAGE_SIZE) {\n break;\n }\n cursor = nextCursor;\n }\n\n return total;\n}\n","/**\n * Implementation of `fiber-pay node stop`.\n */\n\nimport type { CliConfig } from './config.js';\nimport { printJsonError, printJsonSuccess } from './format.js';\nimport { stopRuntimeDaemonFromNode } from './node-runtime-daemon.js';\nimport { isProcessRunning, readPidFile, removePidFile } from './pid.js';\nimport { readRuntimeMeta, readRuntimePid, removeRuntimeFiles } from './runtime-meta.js';\n\nexport interface NodeStopOptions {\n json?: boolean;\n}\n\nexport async function runNodeStopCommand(\n config: CliConfig,\n options: NodeStopOptions,\n): Promise<void> {\n const json = Boolean(options.json);\n\n // Shut down the runtime daemon if running\n const runtimeMeta = readRuntimeMeta(config.dataDir);\n const runtimePid = readRuntimePid(config.dataDir);\n if (runtimeMeta?.daemon && runtimePid && isProcessRunning(runtimePid)) {\n stopRuntimeDaemonFromNode({ dataDir: config.dataDir, rpcUrl: config.rpcUrl });\n }\n removeRuntimeFiles(config.dataDir);\n\n // Check for fnn PID\n const pid = readPidFile(config.dataDir);\n if (!pid) {\n if (json) {\n printJsonError({\n code: 'NODE_NOT_RUNNING',\n message: 'No PID file found. Node may not be running.',\n recoverable: true,\n suggestion: 'Run `fiber-pay node start` first if you intend to stop a node.',\n });\n } else {\n console.log('❌ No PID file found. Node may not be running.');\n }\n process.exit(1);\n }\n\n if (!isProcessRunning(pid)) {\n if (json) {\n printJsonError({\n code: 'NODE_NOT_RUNNING',\n message: `Process ${pid} is not running. Cleaning up PID file.`,\n recoverable: true,\n suggestion: 'Start the node again if needed; stale PID has been cleaned.',\n details: { pid, stalePidFileCleaned: true },\n });\n } else {\n console.log(`❌ Process ${pid} is not running. Cleaning up PID file.`);\n }\n removePidFile(config.dataDir);\n process.exit(1);\n }\n\n if (!json) {\n console.log(`🛑 Stopping node (PID: ${pid})...`);\n }\n process.kill(pid, 'SIGTERM');\n\n // Wait up to 3 seconds for graceful shutdown\n let attempts = 0;\n while (isProcessRunning(pid) && attempts < 30) {\n await new Promise((resolve) => setTimeout(resolve, 100));\n attempts++;\n }\n\n if (isProcessRunning(pid)) {\n process.kill(pid, 'SIGKILL');\n }\n\n removePidFile(config.dataDir);\n if (json) {\n printJsonSuccess({ pid, stopped: true });\n } else {\n console.log('✅ Node stopped.');\n }\n}\n","/**\n * Implementation of `fiber-pay node upgrade`.\n */\n\nimport { BinaryManager, type DownloadProgress, MigrationManager } from '@fiber-pay/node';\nimport { getBinaryManagerInstallDirOrThrow, resolveBinaryPath } from './binary-path.js';\nimport type { CliConfig } from './config.js';\nimport { printJsonError, printJsonSuccess } from './format.js';\nimport { normalizeMigrationCheck, replaceRawMigrateHint } from './migration-utils.js';\nimport { isProcessRunning, readPidFile } from './pid.js';\n\nexport interface NodeUpgradeOptions {\n version?: string;\n backup?: boolean;\n checkOnly?: boolean;\n forceMigrate?: boolean;\n json?: boolean;\n}\n\nexport async function runNodeUpgradeCommand(\n config: CliConfig,\n options: NodeUpgradeOptions,\n): Promise<void> {\n const json = Boolean(options.json);\n const resolvedBinary = resolveBinaryPath(config);\n let installDir: string;\n try {\n installDir = getBinaryManagerInstallDirOrThrow(resolvedBinary);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (json) {\n printJsonError({\n code: 'BINARY_PATH_INCOMPATIBLE',\n message,\n recoverable: true,\n suggestion:\n 'Use `fiber-pay config profile unset binaryPath` or set binaryPath to a standard fnn filename in the target directory.',\n });\n } else {\n console.error(`❌ ${message}`);\n }\n process.exit(1);\n }\n\n const binaryManager = new BinaryManager(installDir);\n\n // Step 1: Check if node is running — must be stopped before upgrade\n const pid = readPidFile(config.dataDir);\n if (pid && isProcessRunning(pid)) {\n const msg = 'The Fiber node is currently running. Stop it before upgrading.';\n if (json) {\n printJsonError({\n code: 'NODE_RUNNING',\n message: msg,\n recoverable: true,\n suggestion: 'Run `fiber-pay node stop` first, then retry the upgrade.',\n });\n } else {\n console.error(`❌ ${msg}`);\n console.log(' Run: fiber-pay node stop');\n }\n process.exit(1);\n }\n\n // Step 2: Resolve target version\n let targetTag: string;\n if (options.version) {\n targetTag = binaryManager.normalizeTag(options.version);\n } else {\n if (!json) console.log('🔍 Resolving latest Fiber release...');\n targetTag = await binaryManager.getLatestTag();\n }\n\n if (!json) console.log(`📦 Target version: ${targetTag}`);\n\n // Step 3: Check current version\n const currentInfo = await binaryManager.getBinaryInfo();\n const targetVersion = targetTag.startsWith('v') ? targetTag.slice(1) : targetTag;\n\n // Step 4: Prepare migration-related paths\n const storePath = MigrationManager.resolveStorePath(config.dataDir);\n const migrateBinaryPath = binaryManager.getMigrateBinaryPath();\n let migrationCheck: Awaited<ReturnType<MigrationManager['check']>> | null = null;\n\n const storeExists = MigrationManager.storeExists(config.dataDir);\n\n if (!json && storeExists) {\n console.log('📂 Existing store detected.');\n }\n\n if (currentInfo.ready && currentInfo.version === targetVersion && !options.forceMigrate) {\n if (storeExists) {\n migrationCheck = await runMigrationAndReport({\n migrateBinaryPath,\n storePath,\n json,\n checkOnly: Boolean(options.checkOnly),\n targetVersion,\n backup: options.backup !== false,\n forceMigrateAttempt: false,\n });\n }\n\n const msg = migrationCheck\n ? `Already installed ${targetTag}. Store compatibility checked.`\n : `Already installed ${targetTag}. Use --force-migrate to run migration flow anyway.`;\n if (json) {\n printJsonSuccess({\n action: 'none',\n currentVersion: currentInfo.version,\n targetVersion,\n message: msg,\n migration: migrationCheck,\n });\n } else {\n console.log(`✅ ${msg}`);\n }\n return;\n }\n\n const versionMatches = currentInfo.ready && currentInfo.version === targetVersion;\n const shouldDownload = !versionMatches;\n\n if (!json && currentInfo.ready) {\n console.log(` Current version: v${currentInfo.version}`);\n }\n\n if (shouldDownload) {\n if (!json && storeExists) {\n console.log('📂 Existing store detected, will check migration after download.');\n }\n\n // Step 5: Download new binary (this also extracts fnn-migrate)\n if (!json) console.log('⬇️ Downloading new binary...');\n\n const showProgress = (progress: DownloadProgress) => {\n if (!json) {\n const percent = progress.percent !== undefined ? ` (${progress.percent}%)` : '';\n process.stdout.write(`\\r [${progress.phase}]${percent} ${progress.message}`.padEnd(80));\n if (progress.phase === 'installing') console.log();\n }\n };\n\n await binaryManager.download({\n version: targetTag,\n force: true,\n onProgress: showProgress,\n });\n } else if (!json && options.forceMigrate) {\n console.log('⏭️ Skipping binary download: target version is already installed.');\n console.log('🔁 --force-migrate enabled: attempting migration flow on existing binaries.');\n }\n\n // Step 6: Check migration if store exists\n if (storeExists) {\n migrationCheck = await runMigrationAndReport({\n migrateBinaryPath,\n storePath,\n json,\n checkOnly: Boolean(options.checkOnly),\n targetVersion,\n backup: options.backup !== false,\n forceMigrateAttempt: Boolean(options.forceMigrate),\n });\n }\n\n // Step 7: Final status\n const newInfo = await binaryManager.getBinaryInfo();\n if (json) {\n printJsonSuccess({\n action: 'upgraded',\n previousVersion: currentInfo.ready ? currentInfo.version : null,\n currentVersion: newInfo.version,\n binaryPath: newInfo.path,\n migrateBinaryPath,\n migration: migrationCheck,\n });\n } else {\n console.log('\\n✅ Upgrade complete!');\n console.log(` Version: v${newInfo.version}`);\n console.log(` Binary: ${newInfo.path}`);\n console.log('\\n Start the node with: fiber-pay node start');\n }\n}\n\n// =============================================================================\n// Internal helpers\n// =============================================================================\n\ninterface MigrationRunOptions {\n migrateBinaryPath: string;\n storePath: string;\n json: boolean;\n checkOnly: boolean;\n targetVersion: string;\n backup: boolean;\n forceMigrateAttempt: boolean;\n}\n\n/**\n * Run migration check (and optionally migrate) after a new binary has been\n * downloaded. Exits the process on unrecoverable errors.\n *\n * @returns The migration check result, or `null` if the caller should return\n * early (e.g. `--check-only`).\n */\nasync function runMigrationAndReport(\n opts: MigrationRunOptions,\n): Promise<Awaited<ReturnType<MigrationManager['check']>> | null> {\n const {\n migrateBinaryPath,\n storePath,\n json,\n checkOnly,\n targetVersion,\n backup,\n forceMigrateAttempt,\n } = opts;\n\n // Instantiate MigrationManager\n let migrationManager: MigrationManager;\n try {\n migrationManager = new MigrationManager(migrateBinaryPath);\n } catch (err) {\n const msg = err instanceof Error ? err.message : 'fnn-migrate binary not available';\n if (json) {\n printJsonError({\n code: 'MIGRATION_TOOL_MISSING',\n message: msg,\n recoverable: true,\n suggestion:\n 'Run `fiber-pay node upgrade` to reinstall binaries, then retry `fiber-pay node upgrade --force-migrate`.',\n });\n } else {\n console.error(`\\n⚠️ ${msg}`);\n console.log(\n ' Run `fiber-pay node upgrade` to reinstall binaries, then retry `fiber-pay node upgrade --force-migrate`.',\n );\n }\n process.exit(1);\n }\n\n // Run check\n if (!json) console.log('🔍 Checking store compatibility...');\n\n let migrationCheck: Awaited<ReturnType<MigrationManager['check']>>;\n try {\n migrationCheck = await migrationManager.check(storePath);\n } catch (checkErr) {\n const msg = checkErr instanceof Error ? checkErr.message : String(checkErr);\n if (json) {\n printJsonError({\n code: 'MIGRATION_TOOL_MISSING',\n message: `Migration check failed: ${msg}`,\n recoverable: true,\n suggestion:\n 'Run `fiber-pay node upgrade` to reinstall binaries, then retry `fiber-pay node upgrade --force-migrate`.',\n });\n } else {\n console.error(`\\n⚠️ Migration check failed: ${msg}`);\n console.log(\n ' Run `fiber-pay node upgrade` to reinstall binaries, then retry `fiber-pay node upgrade --force-migrate`.',\n );\n }\n process.exit(1);\n }\n\n // --check-only: report and let the caller return\n if (checkOnly) {\n const normalizedCheck = normalizeMigrationCheck(migrationCheck);\n if (json) {\n printJsonSuccess({\n action: 'check-only',\n targetVersion,\n migration: normalizedCheck,\n });\n } else {\n console.log(`\\n📋 Migration status: ${normalizedCheck.message}`);\n }\n // Signal to caller to return early\n process.exit(0);\n }\n\n if (!migrationCheck.needed) {\n if (!json) console.log(' Store is compatible, no migration needed.');\n return normalizeMigrationCheck(migrationCheck);\n }\n\n // Breaking change — cannot auto-migrate\n if (!migrationCheck.valid && !forceMigrateAttempt) {\n const normalizedMessage = replaceRawMigrateHint(migrationCheck.message);\n if (json) {\n printJsonError({\n code: 'MIGRATION_INCOMPATIBLE',\n message: normalizedMessage,\n recoverable: false,\n suggestion: `Back up your store first (directory: \"${storePath}\"). Then run \\`fiber-pay node upgrade --force-migrate\\`. If it still fails, close all channels with the old fnn version, remove the store, and restart with a fresh store. If you attempted migration with backup enabled, you can roll back by restoring the backup directory.`,\n details: {\n storePath,\n migrationCheck: {\n ...migrationCheck,\n message: normalizedMessage,\n },\n },\n });\n } else {\n console.error('\\n❌ Store migration is not possible automatically.');\n console.log(normalizedMessage);\n console.log(` 1) Back up store directory: ${storePath}`);\n console.log(' 2) Try: fiber-pay node upgrade --force-migrate');\n console.log(\n ' 3) If it still fails, close channels on old fnn, remove store, then restart.',\n );\n console.log(' 4) If migration created a backup, you can roll back by restoring it.');\n }\n process.exit(1);\n }\n\n if (!migrationCheck.valid && !json) {\n console.log('⚠️ Store check reported incompatibility, but --force-migrate is set.');\n console.log(' Attempting migration anyway with backup enabled (unless --no-backup).');\n }\n\n // Run migration\n if (!json) console.log('🔄 Running database migration...');\n\n const result = await migrationManager.migrate({\n storePath,\n backup,\n force: forceMigrateAttempt,\n });\n\n if (!result.success) {\n if (json) {\n printJsonError({\n code: 'MIGRATION_FAILED',\n message: result.message,\n recoverable: !!result.backupPath,\n suggestion: result.backupPath\n ? `To roll back, delete the current store at \"${storePath}\" and restore the backup from \"${result.backupPath}\".`\n : 'Re-download the previous version or start fresh.',\n details: { output: result.output, backupPath: result.backupPath },\n });\n } else {\n console.error('\\n❌ Migration failed.');\n console.log(result.message);\n }\n process.exit(1);\n }\n\n if (!json) {\n console.log(`✅ ${result.message}`);\n if (result.backupPath) {\n console.log(` Backup: ${result.backupPath}`);\n }\n }\n\n try {\n const postCheck = await migrationManager.check(storePath);\n return normalizeMigrationCheck(postCheck);\n } catch (err) {\n if (!json) {\n const message = err instanceof Error ? err.message : String(err);\n console.error('⚠️ Post-migration check failed; final migration status may be stale.');\n console.error(` ${message}`);\n }\n return normalizeMigrationCheck(migrationCheck);\n }\n}\n","import type { RouterHop } from '@fiber-pay/sdk';\nimport { ckbToShannons, type HexString, shannonsToCkb } from '@fiber-pay/sdk';\nimport { Command } from 'commander';\nimport { sleep } from '../lib/async.js';\nimport type { CliConfig } from '../lib/config.js';\nimport {\n formatPaymentResult,\n printJsonError,\n printJsonEvent,\n printJsonSuccess,\n printPaymentDetailHuman,\n} from '../lib/format.js';\nimport { createReadyRpcClient, resolveRpcEndpoint } from '../lib/rpc.js';\nimport {\n type RuntimeJobRecord,\n tryCreateRuntimePaymentJob,\n waitForRuntimeJobTerminal,\n} from '../lib/runtime-jobs.js';\nimport { registerPaymentRebalanceCommand } from './rebalance.js';\n\nexport function createPaymentCommand(config: CliConfig): Command {\n const payment = new Command('payment').description('Payment lifecycle and status commands');\n\n payment\n .command('send')\n .argument('[invoice]')\n .option('--invoice <invoice>')\n .option('--to <nodeId>')\n .option('--amount <ckb>')\n .option('--max-fee <ckb>')\n .option('--wait', 'Wait for runtime job terminal status when runtime proxy is active')\n .option('--timeout <seconds>', 'Wait timeout for --wait mode', '120')\n .option('--json')\n .action(async (invoiceArg, options) => {\n const rpc = await createReadyRpcClient(config);\n const json = Boolean(options.json);\n const invoice = options.invoice || invoiceArg;\n const recipientNodeId = options.to;\n const amountCkb = options.amount ? parseFloat(options.amount) : undefined;\n const maxFeeCkb = options.maxFee ? parseFloat(options.maxFee) : undefined;\n const shouldWait = Boolean(options.wait);\n const timeoutSeconds = parseInt(String(options.timeout ?? '120'), 10);\n\n if (!invoice && !recipientNodeId) {\n if (json) {\n printJsonError({\n code: 'PAYMENT_SEND_INPUT_INVALID',\n message: 'Either invoice or --to <nodeId> required',\n recoverable: true,\n suggestion: 'Provide a valid invoice, or provide both `--to` and `--amount`.',\n });\n } else {\n console.error('Error: Either invoice or --to <nodeId> required');\n }\n process.exit(1);\n }\n if (recipientNodeId && !amountCkb) {\n if (json) {\n printJsonError({\n code: 'PAYMENT_SEND_INPUT_INVALID',\n message: '--amount required when using --to',\n recoverable: true,\n suggestion: 'Add `--amount <ckb>` when using keysend mode (`--to`).',\n });\n } else {\n console.error('Error: --amount required when using --to');\n }\n process.exit(1);\n }\n\n const paymentParams = {\n invoice,\n target_pubkey: recipientNodeId as HexString | undefined,\n amount: amountCkb ? ckbToShannons(amountCkb) : undefined,\n keysend: recipientNodeId ? true : undefined,\n max_fee_amount: maxFeeCkb ? ckbToShannons(maxFeeCkb) : undefined,\n };\n\n const endpoint = resolveRpcEndpoint(config);\n\n if (endpoint.target === 'runtime-proxy') {\n const created = await tryCreateRuntimePaymentJob(endpoint.url, {\n params: {\n invoice,\n sendPaymentParams: paymentParams,\n },\n options: {\n idempotencyKey: invoice ? `payment:invoice:${invoice}` : undefined,\n },\n });\n\n if (created) {\n const job = shouldWait\n ? await waitForRuntimeJobTerminal(endpoint.url, created.id, timeoutSeconds)\n : created;\n\n const payload = {\n paymentHash: getJobPaymentHash(job) ?? 'unknown',\n status:\n job.state === 'succeeded'\n ? 'success'\n : job.state === 'failed' || job.state === 'cancelled'\n ? 'failed'\n : 'pending',\n feeCkb: getJobFeeCkb(job),\n failureReason: getJobFailure(job),\n jobId: job.id,\n jobState: job.state,\n };\n\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log('Payment job submitted');\n console.log(` Job: ${payload.jobId}`);\n console.log(` Hash: ${payload.paymentHash}`);\n console.log(` Status: ${payload.status} (${payload.jobState})`);\n console.log(` Fee: ${payload.feeCkb} CKB`);\n if (payload.failureReason) {\n console.log(` Error: ${payload.failureReason}`);\n }\n }\n return;\n }\n }\n\n // Fallback to direct RPC send_payment\n const result = await rpc.sendPayment(paymentParams);\n\n const payload = {\n paymentHash: result.payment_hash,\n status:\n result.status === 'Success'\n ? 'success'\n : result.status === 'Failed'\n ? 'failed'\n : 'pending',\n feeCkb: shannonsToCkb(result.fee),\n failureReason: result.failed_error,\n };\n\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log('Payment sent');\n console.log(` Hash: ${payload.paymentHash}`);\n console.log(` Status: ${payload.status}`);\n console.log(` Fee: ${payload.feeCkb} CKB`);\n if (payload.failureReason) {\n console.log(` Error: ${payload.failureReason}`);\n }\n }\n });\n\n registerPaymentRebalanceCommand(payment, config);\n\n payment\n .command('get')\n .argument('<paymentHash>')\n .option('--json')\n .action(async (paymentHash, options) => {\n const rpc = await createReadyRpcClient(config);\n const result = await rpc.getPayment({ payment_hash: paymentHash as HexString });\n if (options.json) {\n printJsonSuccess(formatPaymentResult(result));\n } else {\n printPaymentDetailHuman(result);\n }\n });\n\n payment\n .command('watch')\n .argument('<paymentHash>')\n .option('--interval <seconds>', 'Polling interval', '2')\n .option('--timeout <seconds>', 'Timeout', '120')\n .option('--until <target>', 'SUCCESS | FAILED | TERMINAL', 'TERMINAL')\n .option('--on-timeout <behavior>', 'fail | success', 'fail')\n .option('--json')\n .action(async (paymentHash, options) => {\n const json = Boolean(options.json);\n const intervalSeconds = parseInt(options.interval, 10);\n const timeoutSeconds = parseInt(options.timeout, 10);\n const until = String(options.until ?? 'TERMINAL')\n .trim()\n .toUpperCase();\n const onTimeout = String(options.onTimeout ?? 'fail')\n .trim()\n .toLowerCase();\n if (!['SUCCESS', 'FAILED', 'TERMINAL'].includes(until)) {\n if (json) {\n printJsonError({\n code: 'PAYMENT_WATCH_INPUT_INVALID',\n message: `Invalid --until value: ${options.until}. Expected SUCCESS, FAILED, or TERMINAL`,\n recoverable: true,\n suggestion: 'Use one of: SUCCESS, FAILED, TERMINAL.',\n details: { provided: options.until, expected: ['SUCCESS', 'FAILED', 'TERMINAL'] },\n });\n } else {\n console.error(\n `Error: Invalid --until value: ${options.until}. Expected SUCCESS, FAILED, or TERMINAL`,\n );\n }\n process.exit(1);\n }\n if (!['fail', 'success'].includes(onTimeout)) {\n if (json) {\n printJsonError({\n code: 'PAYMENT_WATCH_INPUT_INVALID',\n message: `Invalid --on-timeout value: ${options.onTimeout}. Expected fail or success`,\n recoverable: true,\n suggestion: 'Use `--on-timeout fail` or `--on-timeout success`.',\n details: { provided: options.onTimeout, expected: ['fail', 'success'] },\n });\n } else {\n console.error(\n `Error: Invalid --on-timeout value: ${options.onTimeout}. Expected fail or success`,\n );\n }\n process.exit(1);\n }\n const rpc = await createReadyRpcClient(config);\n const startedAt = Date.now();\n let lastStatus: string | undefined;\n\n while (Date.now() - startedAt < timeoutSeconds * 1000) {\n const paymentResult = await rpc.getPayment({ payment_hash: paymentHash as HexString });\n\n if (paymentResult.status !== lastStatus) {\n if (json) {\n printJsonEvent('status_transition', {\n statusTransition: {\n from: lastStatus ?? null,\n to: paymentResult.status,\n },\n payment: formatPaymentResult(paymentResult),\n });\n } else {\n console.log(`Status: ${lastStatus ?? '(initial)'} -> ${paymentResult.status}`);\n printPaymentDetailHuman(paymentResult);\n console.log('');\n }\n lastStatus = paymentResult.status;\n }\n\n const isSuccess = paymentResult.status === 'Success';\n const isFailed = paymentResult.status === 'Failed';\n const terminalReached =\n until === 'TERMINAL' ? isSuccess || isFailed : until === 'SUCCESS' ? isSuccess : isFailed;\n\n if (terminalReached) {\n if (json) {\n printJsonEvent('terminal', {\n paymentHash,\n terminalStatus: paymentResult.status,\n until,\n });\n }\n return;\n }\n\n if ((isSuccess || isFailed) && until !== 'TERMINAL') {\n if (json) {\n printJsonError({\n code: 'PAYMENT_WATCH_UNEXPECTED_TERMINAL',\n message: `Payment reached ${paymentResult.status} before requested --until ${until}`,\n recoverable: true,\n suggestion: 'Set `--until TERMINAL` or handle mismatched terminal state in caller.',\n details: { terminalStatus: paymentResult.status, until },\n });\n } else {\n console.error(\n `Error: Payment reached ${paymentResult.status} before requested --until ${until}`,\n );\n }\n process.exit(1);\n }\n\n await sleep(intervalSeconds * 1000);\n }\n\n if (onTimeout === 'success') {\n if (json) {\n printJsonEvent('terminal', {\n paymentHash,\n terminalStatus: 'Timeout',\n until,\n timeoutSeconds,\n });\n } else {\n console.log(\n `Timeout reached (${timeoutSeconds}s) and treated as success by --on-timeout=success.`,\n );\n }\n return;\n }\n\n if (json) {\n printJsonError({\n code: 'PAYMENT_WATCH_TIMEOUT',\n message: `Payment ${paymentHash} did not reach terminal state within ${timeoutSeconds}s`,\n recoverable: true,\n suggestion: 'Increase timeout, or continue polling using `payment get --json`.',\n details: { paymentHash, timeoutSeconds },\n });\n } else {\n console.error(\n `Error: Payment ${paymentHash} did not reach terminal state within ${timeoutSeconds}s`,\n );\n }\n process.exit(1);\n });\n\n payment\n .command('route')\n .description('Build a payment route through specified hops')\n .requiredOption('--hops <pubkeys>', 'Comma-separated list of node pubkeys forming the route')\n .option('--amount <ckb>', 'Amount in CKB to route')\n .option('--json')\n .action(async (options) => {\n const rpc = await createReadyRpcClient(config);\n const json = Boolean(options.json);\n const pubkeys = (options.hops as string).split(',').map((s: string) => s.trim());\n\n if (pubkeys.length === 0 || pubkeys.some((pk: string) => !pk)) {\n const msg = '--hops must be a non-empty comma-separated list of pubkeys';\n if (json) {\n printJsonError({\n code: 'PAYMENT_ROUTE_INPUT_INVALID',\n message: msg,\n recoverable: true,\n suggestion: 'Provide pubkeys: --hops 0xabc...,0xdef...',\n });\n } else {\n console.error(`Error: ${msg}`);\n }\n process.exit(1);\n }\n\n const hopsInfo = pubkeys.map((pubkey: string) => ({ pubkey: pubkey as HexString }));\n const amount = options.amount ? ckbToShannons(parseFloat(options.amount)) : undefined;\n\n const result = await rpc.buildRouter({\n hops_info: hopsInfo,\n amount,\n });\n\n if (json) {\n printJsonSuccess({ routerHops: result.router_hops });\n } else {\n console.log(`Route built: ${result.router_hops.length} hop(s)`);\n for (let i = 0; i < result.router_hops.length; i++) {\n const hop = result.router_hops[i];\n console.log(` #${i + 1}`);\n console.log(` Target: ${hop.target}`);\n console.log(\n ` Outpoint: ${hop.channel_outpoint.tx_hash}:${hop.channel_outpoint.index}`,\n );\n console.log(` Amount: ${shannonsToCkb(hop.amount_received)} CKB`);\n console.log(` Expiry: ${hop.incoming_tlc_expiry}`);\n }\n }\n });\n\n payment\n .command('send-route')\n .description('Send a payment using a pre-built route from `payment route`')\n .requiredOption(\n '--router <json>',\n 'JSON array of router hops (output of `payment route --json`)',\n )\n .option('--invoice <invoice>', 'Invoice to pay')\n .option('--payment-hash <hash>', 'Payment hash (for keysend)')\n .option('--keysend', 'Keysend mode')\n .option('--allow-self-payment', 'Allow self-payment for circular route rebalancing')\n .option('--dry-run', 'Simulate—do not actually send')\n .option('--json')\n .action(async (options) => {\n const rpc = await createReadyRpcClient(config);\n const json = Boolean(options.json);\n\n let router: RouterHop[];\n try {\n router = JSON.parse(options.router as string) as RouterHop[];\n } catch {\n const msg = '--router must be a valid JSON array of router hops';\n if (json) {\n printJsonError({\n code: 'PAYMENT_SEND_ROUTE_INPUT_INVALID',\n message: msg,\n recoverable: true,\n suggestion: 'Pipe --json output of `payment route` into this flag.',\n });\n } else {\n console.error(`Error: ${msg}`);\n }\n process.exit(1);\n }\n\n const result = await rpc.sendPaymentWithRouter({\n router,\n invoice: options.invoice as string | undefined,\n payment_hash: options.paymentHash as HexString | undefined,\n keysend: options.keysend ? true : undefined,\n allow_self_payment: options.allowSelfPayment ? true : undefined,\n dry_run: options.dryRun ? true : undefined,\n });\n\n const payload = {\n paymentHash: result.payment_hash,\n status:\n result.status === 'Success'\n ? 'success'\n : result.status === 'Failed'\n ? 'failed'\n : 'pending',\n feeCkb: shannonsToCkb(result.fee),\n failureReason: result.failed_error,\n dryRun: Boolean(options.dryRun),\n };\n\n if (json) {\n printJsonSuccess(payload);\n } else {\n console.log(options.dryRun ? 'Payment dry-run complete' : 'Payment sent via route');\n console.log(` Hash: ${payload.paymentHash}`);\n console.log(` Status: ${payload.status}`);\n console.log(` Fee: ${payload.feeCkb} CKB`);\n if (payload.failureReason) {\n console.log(` Error: ${payload.failureReason}`);\n }\n }\n });\n\n return payment;\n}\n\nfunction getJobPaymentHash(job: RuntimeJobRecord): string | undefined {\n const result = job.result as { paymentHash?: string } | undefined;\n return result?.paymentHash;\n}\n\nfunction getJobFeeCkb(job: RuntimeJobRecord): number {\n const result = job.result as { fee?: string } | undefined;\n return result?.fee ? shannonsToCkb(result.fee as HexString) : 0;\n}\n\nfunction getJobFailure(job: RuntimeJobRecord): string | undefined {\n const result = job.result as { failedError?: string } | undefined;\n return result?.failedError ?? job.error?.message;\n}\n","import { Command } from 'commander';\nimport type { CliConfig } from '../lib/config.js';\nimport { printJsonSuccess, printPeerListHuman } from '../lib/format.js';\nimport { createReadyRpcClient } from '../lib/rpc.js';\n\nfunction extractPeerIdFromMultiaddr(address: string): string | undefined {\n const match = address.match(/\\/p2p\\/([^/]+)$/);\n return match?.[1];\n}\n\nasync function waitForPeerConnected(\n rpc: Awaited<ReturnType<typeof createReadyRpcClient>>,\n peerId: string,\n timeoutMs: number,\n): Promise<boolean> {\n const start = Date.now();\n while (Date.now() - start < timeoutMs) {\n const peers = await rpc.listPeers();\n if (peers.peers.some((peer) => peer.peer_id === peerId)) {\n return true;\n }\n await new Promise((resolve) => setTimeout(resolve, 500));\n }\n return false;\n}\n\nexport function createPeerCommand(config: CliConfig): Command {\n const peer = new Command('peer').description('Peer management');\n\n peer\n .command('list')\n .option('--json')\n .action(async (options) => {\n const rpc = await createReadyRpcClient(config);\n const peers = await rpc.listPeers();\n if (options.json) {\n printJsonSuccess(peers);\n } else {\n printPeerListHuman(peers.peers);\n }\n });\n\n peer\n .command('connect')\n .argument('<multiaddr>')\n .option('--timeout <sec>', 'Wait timeout for peer to appear in peer list', '8')\n .option('--json')\n .action(async (address, options) => {\n const rpc = await createReadyRpcClient(config);\n const peerId = extractPeerIdFromMultiaddr(address);\n if (!peerId) {\n throw new Error('Invalid multiaddr: missing /p2p/<peerId> suffix');\n }\n\n await rpc.connectPeer({ address });\n const timeoutMs = Math.max(1, Number.parseInt(String(options.timeout), 10) || 8) * 1000;\n const connected = await waitForPeerConnected(rpc, peerId, timeoutMs);\n\n if (!connected) {\n throw new Error(\n `connect_peer accepted but peer not found in list within ${Math.floor(timeoutMs / 1000)}s (${peerId})`,\n );\n }\n\n if (options.json) {\n printJsonSuccess({ address, peerId, message: 'Connected' });\n } else {\n console.log('✅ Connected to peer');\n console.log(` Address: ${address}`);\n console.log(` Peer ID: ${peerId}`);\n }\n });\n\n peer\n .command('disconnect')\n .argument('<peerId>')\n .option('--json')\n .action(async (peerId, options) => {\n const rpc = await createReadyRpcClient(config);\n await rpc.disconnectPeer({ peer_id: peerId });\n\n if (options.json) {\n printJsonSuccess({ peerId, message: 'Disconnected' });\n } else {\n console.log('✅ Disconnected peer');\n console.log(` Peer ID: ${peerId}`);\n }\n });\n\n return peer;\n}\n","import { spawn } from 'node:child_process';\nimport { join, resolve } from 'node:path';\nimport type { Alert, AlertPriority, AlertType, RuntimeConfigInput } from '@fiber-pay/runtime';\nimport {\n alertPriorityOrder,\n formatRuntimeAlert,\n isAlertPriority,\n isAlertType,\n startRuntimeService,\n} from '@fiber-pay/runtime';\nimport { Command } from 'commander';\nimport type { CliConfig } from '../lib/config.js';\nimport { printJsonError, printJsonEvent, printJsonSuccess } from '../lib/format.js';\nimport { resolveLogDirForDateWithOptions } from '../lib/log-files.js';\nimport { parseBoolOption, parseIntegerOption } from '../lib/parse-options.js';\nimport { isProcessRunning } from '../lib/pid.js';\nimport {\n readRuntimeMeta,\n readRuntimePid,\n removeRuntimeFiles,\n writeRuntimeMeta,\n writeRuntimePid,\n} from '../lib/runtime-meta.js';\nimport {\n findListeningProcessByPort,\n isFiberRuntimeCommand,\n terminateProcess,\n} from '../lib/runtime-port.js';\n\ninterface RuntimeLogFilter {\n minPriority?: AlertPriority;\n types?: Set<AlertType>;\n}\n\nfunction formatRuntimeAlertLine(alert: Alert): string {\n return formatRuntimeAlert(alert);\n}\n\nfunction parseAlertPriorityOption(value: string | undefined): AlertPriority | undefined {\n if (!value) {\n return undefined;\n }\n const normalized = value.trim().toLowerCase();\n if (!isAlertPriority(normalized)) {\n throw new Error(`Invalid log-min-priority: ${value}. Expected critical|high|medium|low.`);\n }\n return normalized;\n}\n\nfunction parseAlertTypesOption(value: string | undefined): Set<AlertType> | undefined {\n if (!value) {\n return undefined;\n }\n\n const tokens = value\n .split(',')\n .map((token) => token.trim())\n .filter((token) => token.length > 0);\n\n if (tokens.length === 0) {\n return undefined;\n }\n\n const result = new Set<AlertType>();\n for (const token of tokens) {\n if (!isAlertType(token)) {\n throw new Error(`Invalid log-type: ${token}. Use runtime alert type names, comma-separated.`);\n }\n result.add(token);\n }\n\n return result;\n}\n\nfunction shouldPrintAlert(alert: Alert, filter: RuntimeLogFilter): boolean {\n if (filter.minPriority) {\n const minimumRank = alertPriorityOrder[filter.minPriority];\n if (alertPriorityOrder[alert.priority] < minimumRank) {\n return false;\n }\n }\n\n if (filter.types && filter.types.size > 0 && !filter.types.has(alert.type)) {\n return false;\n }\n\n return true;\n}\n\nfunction resolveRuntimeRecoveryListen(config: CliConfig): string {\n const meta = readRuntimeMeta(config.dataDir);\n return meta?.proxyListen ?? config.runtimeProxyListen ?? '127.0.0.1:8229';\n}\n\nexport function createRuntimeCommand(config: CliConfig): Command {\n const runtime = new Command('runtime').description('Polling monitor and alert runtime service');\n\n runtime\n .command('start')\n .description('Start runtime monitor service in foreground')\n .option('--daemon', 'Start runtime monitor in detached background mode')\n .option('--fiber-rpc-url <url>', 'Target fiber rpc URL (defaults to --rpc-url/global config)')\n .option('--proxy-listen <host:port>', 'Monitor proxy listen address')\n .option('--channel-poll-ms <ms>', 'Channel polling interval in milliseconds')\n .option('--invoice-poll-ms <ms>', 'Invoice polling interval in milliseconds')\n .option('--payment-poll-ms <ms>', 'Payment polling interval in milliseconds')\n .option('--peer-poll-ms <ms>', 'Peer polling interval in milliseconds')\n .option('--health-poll-ms <ms>', 'RPC health polling interval in milliseconds')\n .option('--include-closed <bool>', 'Monitor closed channels (true|false)')\n .option('--completed-ttl-seconds <seconds>', 'TTL for completed invoices/payments in tracker')\n .option('--state-file <path>', 'State file path for snapshots and history')\n .option('--alert-log-file <path>', 'Path to runtime alert JSONL log file (legacy static path)')\n .option('--alert-logs-base-dir <dir>', 'Base logs directory for daily-rotated alert files')\n .option('--flush-ms <ms>', 'State flush interval in milliseconds')\n .option('--webhook <url>', 'Webhook URL to receive alert POST payloads')\n .option('--websocket <host:port>', 'WebSocket alert broadcast listen address')\n .option(\n '--log-min-priority <priority>',\n 'Minimum runtime log priority (critical|high|medium|low)',\n )\n .option('--log-type <types>', 'Comma-separated runtime alert types to print')\n .option('--json')\n .action(async (options) => {\n const asJson = Boolean(options.json);\n const daemon = Boolean(options.daemon);\n const isRuntimeChild = process.env.FIBER_RUNTIME_CHILD === '1';\n const runtimeListen = String(\n options.proxyListen ?? config.runtimeProxyListen ?? '127.0.0.1:8229',\n );\n\n try {\n const existingPid = readRuntimePid(config.dataDir);\n if (\n existingPid &&\n isProcessRunning(existingPid) &&\n (!isRuntimeChild || existingPid !== process.pid)\n ) {\n const message = `Runtime already running (PID: ${existingPid})`;\n if (asJson) {\n printJsonError({\n code: 'RUNTIME_ALREADY_RUNNING',\n message,\n recoverable: true,\n suggestion: 'Run `fiber-pay runtime status` or `fiber-pay runtime stop` first.',\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n if (existingPid && !isProcessRunning(existingPid)) {\n removeRuntimeFiles(config.dataDir);\n }\n\n const discovered = findListeningProcessByPort(runtimeListen);\n if (discovered && (!existingPid || discovered.pid !== existingPid)) {\n if (isFiberRuntimeCommand(discovered.command)) {\n const terminated = await terminateProcess(discovered.pid);\n if (!terminated) {\n throw new Error(\n `Runtime port ${runtimeListen} is occupied by stale fiber-pay runtime PID ${discovered.pid} but termination failed.`,\n );\n }\n removeRuntimeFiles(config.dataDir);\n if (!asJson) {\n console.log(\n `Recovered stale runtime process on ${runtimeListen} (PID: ${discovered.pid}).`,\n );\n }\n } else if (discovered.command) {\n const details = discovered.command\n ? `PID ${discovered.pid} (${discovered.command})`\n : `PID ${discovered.pid}`;\n throw new Error(\n `Runtime proxy listen ${runtimeListen} is already in use by non-fiber-pay process: ${details}`,\n );\n } else {\n throw new Error(\n `Runtime proxy listen ${runtimeListen} is already in use by process PID ${discovered.pid}. ` +\n 'Unable to determine the owning command; inspect this PID manually before retrying.',\n );\n }\n }\n\n if (daemon && !isRuntimeChild) {\n const childArgv = process.argv.filter((arg) => arg !== '--daemon');\n const child = spawn(process.execPath, childArgv.slice(1), {\n detached: true,\n stdio: 'ignore',\n cwd: process.cwd(),\n env: {\n ...process.env,\n FIBER_RUNTIME_CHILD: '1',\n },\n });\n child.unref();\n\n const childPid = child.pid;\n if (!childPid) {\n throw new Error('Failed to spawn runtime daemon process');\n }\n\n writeRuntimePid(config.dataDir, childPid);\n\n if (asJson) {\n printJsonSuccess({\n daemon: true,\n pid: childPid,\n message: 'Runtime daemon starting',\n });\n } else {\n console.log(`Runtime daemon starting (PID: ${childPid})`);\n }\n return;\n }\n\n const runtimeConfig: RuntimeConfigInput = {\n fiberRpcUrl: String(options.fiberRpcUrl ?? config.rpcUrl),\n channelPollIntervalMs: parseIntegerOption(options.channelPollMs, 'channel-poll-ms'),\n invoicePollIntervalMs: parseIntegerOption(options.invoicePollMs, 'invoice-poll-ms'),\n paymentPollIntervalMs: parseIntegerOption(options.paymentPollMs, 'payment-poll-ms'),\n peerPollIntervalMs: parseIntegerOption(options.peerPollMs, 'peer-poll-ms'),\n healthPollIntervalMs: parseIntegerOption(options.healthPollMs, 'health-poll-ms'),\n includeClosedChannels: parseBoolOption(options.includeClosed, 'include-closed'),\n completedItemTtlSeconds: parseIntegerOption(\n options.completedTtlSeconds,\n 'completed-ttl-seconds',\n ),\n proxy: {\n enabled: true,\n listen: runtimeListen,\n },\n storage: {\n stateFilePath: options.stateFile\n ? resolve(String(options.stateFile))\n : resolve(config.dataDir, 'runtime-state.json'),\n flushIntervalMs: parseIntegerOption(options.flushMs, 'flush-ms'),\n },\n jobs: {\n enabled: true,\n dbPath: resolve(config.dataDir, 'runtime-jobs.db'),\n },\n };\n\n // Determine alert backend: prefer daily-file rotation, fall back to static file\n let alertLogsBaseDir: string | undefined;\n let alertLogFile: string | undefined;\n\n if (options.alertLogsBaseDir) {\n alertLogsBaseDir = resolve(String(options.alertLogsBaseDir));\n } else if (options.alertLogFile) {\n alertLogFile = resolve(String(options.alertLogFile));\n } else {\n alertLogsBaseDir = resolve(config.dataDir, 'logs');\n }\n\n const alerts: RuntimeConfigInput['alerts'] = [{ type: 'stdout' }];\n if (alertLogsBaseDir) {\n alerts.push({ type: 'daily-file', baseLogsDir: alertLogsBaseDir });\n } else if (alertLogFile) {\n alerts.push({ type: 'file', path: alertLogFile });\n }\n if (options.webhook) {\n alerts.push({ type: 'webhook', url: String(options.webhook) });\n }\n if (options.websocket) {\n alerts.push({ type: 'websocket', listen: String(options.websocket) });\n }\n runtimeConfig.alerts = alerts;\n\n const logFilter: RuntimeLogFilter = {\n minPriority: parseAlertPriorityOption(options.logMinPriority),\n types: parseAlertTypesOption(options.logType),\n };\n\n if (asJson) {\n printJsonEvent('runtime_starting', {\n fiberRpcUrl: runtimeConfig.fiberRpcUrl,\n proxyListen: runtimeConfig.proxy?.listen,\n });\n } else {\n console.log('Starting fiber runtime monitor...');\n }\n\n const runtime = await startRuntimeService(runtimeConfig);\n const status = runtime.service.getStatus();\n\n const logsBaseDir = alertLogsBaseDir ?? resolve(config.dataDir, 'logs');\n const todayLogDir = resolveLogDirForDateWithOptions(config.dataDir, undefined, {\n logsBaseDir,\n ensureExists: false,\n });\n const effectiveAlertLogPath = alertLogsBaseDir\n ? join(todayLogDir, 'runtime.alerts.jsonl')\n : (alertLogFile ?? join(todayLogDir, 'runtime.alerts.jsonl'));\n\n writeRuntimePid(config.dataDir, process.pid);\n writeRuntimeMeta(config.dataDir, {\n pid: process.pid,\n startedAt: status.startedAt,\n fiberRpcUrl: status.targetUrl,\n proxyListen: status.proxyListen,\n stateFilePath: runtimeConfig.storage?.stateFilePath,\n alertLogFilePath: effectiveAlertLogPath,\n fnnStdoutLogPath: join(todayLogDir, 'fnn.stdout.log'),\n fnnStderrLogPath: join(todayLogDir, 'fnn.stderr.log'),\n logsBaseDir,\n daemon: daemon || isRuntimeChild,\n });\n\n runtime.service.on('alert', (alert) => {\n if (!shouldPrintAlert(alert, logFilter)) {\n return;\n }\n\n if (asJson) {\n printJsonEvent('runtime_alert', alert);\n return;\n }\n console.log(formatRuntimeAlertLine(alert));\n });\n\n if (asJson) {\n printJsonSuccess({\n status: 'running',\n fiberRpcUrl: status.targetUrl,\n proxyListen: status.proxyListen,\n stateFilePath: runtimeConfig.storage?.stateFilePath,\n alertLogFile: effectiveAlertLogPath,\n logsBaseDir,\n });\n printJsonEvent('runtime_started', status);\n } else {\n console.log(`Fiber RPC: ${status.targetUrl}`);\n console.log(`Proxy listen: ${status.proxyListen}`);\n console.log(`State file: ${runtimeConfig.storage?.stateFilePath}`);\n console.log(`Logs dir: ${logsBaseDir}`);\n console.log(`Alert log: ${effectiveAlertLogPath}`);\n console.log('Runtime monitor is running. Press Ctrl+C to stop.');\n }\n\n const signal = await runtime.waitForShutdownSignal();\n\n if (asJson) {\n printJsonEvent('runtime_stopping', { signal });\n } else {\n console.log(`Stopping runtime monitor on ${signal}...`);\n }\n\n await runtime.stop();\n removeRuntimeFiles(config.dataDir);\n\n if (asJson) {\n printJsonEvent('runtime_stopped', { signal });\n } else {\n console.log('Runtime monitor stopped.');\n }\n } catch (error) {\n removeRuntimeFiles(config.dataDir);\n const message = error instanceof Error ? error.message : String(error);\n if (asJson) {\n printJsonError({\n code: 'RUNTIME_START_FAILED',\n message,\n recoverable: true,\n suggestion: 'Check RPC URL reachability and runtime option values, then retry.',\n });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n }\n });\n\n runtime\n .command('status')\n .description('Show runtime process and health status')\n .option('--json')\n .action(async (options) => {\n const asJson = Boolean(options.json);\n let pid = readRuntimePid(config.dataDir);\n const meta = readRuntimeMeta(config.dataDir);\n const recoveryListen = resolveRuntimeRecoveryListen(config);\n\n if (!pid) {\n const fallback = findListeningProcessByPort(recoveryListen);\n if (fallback && isFiberRuntimeCommand(fallback.command)) {\n pid = fallback.pid;\n writeRuntimePid(config.dataDir, pid);\n } else if (fallback?.command) {\n const details = fallback.command\n ? `PID ${fallback.pid} (${fallback.command})`\n : `PID ${fallback.pid}`;\n if (asJson) {\n printJsonError({\n code: 'RUNTIME_PORT_IN_USE',\n message: `Runtime proxy port is in use by non-fiber-pay process: ${details}`,\n recoverable: true,\n suggestion: 'Stop that process or use a different --proxy-listen port.',\n });\n } else {\n console.log(`Runtime proxy port is in use by non-fiber-pay process: ${details}`);\n }\n process.exit(1);\n } else if (fallback) {\n const message =\n `Runtime proxy port is in use by process PID ${fallback.pid}. ` +\n 'The owning command could not be determined; inspect this PID manually.';\n if (asJson) {\n printJsonError({\n code: 'RUNTIME_PORT_IN_USE',\n message,\n recoverable: true,\n suggestion: 'Inspect the PID owner manually or use a different --proxy-listen port.',\n });\n } else {\n console.log(message);\n }\n process.exit(1);\n }\n }\n\n if (!pid) {\n if (asJson) {\n printJsonError({\n code: 'RUNTIME_NOT_RUNNING',\n message: 'Runtime PID file not found.',\n recoverable: true,\n suggestion: 'Start runtime with `fiber-pay runtime start --daemon`.',\n });\n } else {\n console.log('Runtime is not running.');\n }\n process.exit(1);\n }\n\n const running = isProcessRunning(pid);\n if (!running) {\n removeRuntimeFiles(config.dataDir);\n if (asJson) {\n printJsonError({\n code: 'RUNTIME_NOT_RUNNING',\n message: `Runtime process ${pid} is not running. Stale runtime files cleaned.`,\n recoverable: true,\n suggestion: 'Start runtime again with `fiber-pay runtime start`.',\n details: { pid, staleFilesCleaned: true },\n });\n } else {\n console.log(`Runtime process ${pid} is not running. Stale runtime files cleaned.`);\n }\n process.exit(1);\n }\n\n let rpcStatus: unknown;\n if (meta?.proxyListen ?? recoveryListen) {\n try {\n const response = await fetch(\n `http://${meta?.proxyListen ?? recoveryListen}/monitor/status`,\n );\n if (response.ok) {\n rpcStatus = await response.json();\n }\n } catch {\n rpcStatus = undefined;\n }\n }\n\n const payload = {\n running: true,\n pid,\n meta,\n proxyStatus: rpcStatus,\n };\n\n if (asJson) {\n printJsonSuccess(payload);\n } else {\n console.log(`Runtime is running (PID: ${pid})`);\n if (meta?.fiberRpcUrl) {\n console.log(`Fiber RPC: ${meta.fiberRpcUrl}`);\n }\n if (meta?.proxyListen) {\n console.log(`Proxy listen: ${meta.proxyListen}`);\n }\n }\n });\n\n runtime\n .command('stop')\n .description('Stop runtime process by PID')\n .option('--json')\n .action(async (options) => {\n const asJson = Boolean(options.json);\n let pid = readRuntimePid(config.dataDir);\n const recoveryListen = resolveRuntimeRecoveryListen(config);\n\n if (!pid) {\n const fallback = findListeningProcessByPort(recoveryListen);\n if (fallback && isFiberRuntimeCommand(fallback.command)) {\n pid = fallback.pid;\n writeRuntimePid(config.dataDir, pid);\n } else if (fallback?.command) {\n const details = fallback.command\n ? `PID ${fallback.pid} (${fallback.command})`\n : `PID ${fallback.pid}`;\n if (asJson) {\n printJsonError({\n code: 'RUNTIME_PORT_IN_USE',\n message: `Runtime proxy port is in use by non-fiber-pay process: ${details}`,\n recoverable: true,\n suggestion:\n 'Stop that process manually; it is not managed by fiber-pay runtime PID files.',\n });\n } else {\n console.log(`Runtime proxy port is in use by non-fiber-pay process: ${details}`);\n }\n process.exit(1);\n } else if (fallback) {\n const message =\n `Runtime proxy port is in use by process PID ${fallback.pid}. ` +\n 'The owning command could not be determined; inspect this PID manually.';\n if (asJson) {\n printJsonError({\n code: 'RUNTIME_PORT_IN_USE',\n message,\n recoverable: true,\n suggestion:\n 'Inspect the PID owner manually; it may not be managed by fiber-pay runtime PID files.',\n });\n } else {\n console.log(message);\n }\n process.exit(1);\n }\n }\n\n if (!pid) {\n if (asJson) {\n printJsonError({\n code: 'RUNTIME_NOT_RUNNING',\n message: 'Runtime PID file not found.',\n recoverable: true,\n suggestion: 'Start runtime first with `fiber-pay runtime start --daemon`.',\n });\n } else {\n console.log('Runtime is not running.');\n }\n process.exit(1);\n }\n\n if (!isProcessRunning(pid)) {\n removeRuntimeFiles(config.dataDir);\n if (asJson) {\n printJsonError({\n code: 'RUNTIME_NOT_RUNNING',\n message: `Runtime process ${pid} is not running. Stale runtime files cleaned.`,\n recoverable: true,\n suggestion: 'Start runtime again if needed.',\n details: { pid, staleFilesCleaned: true },\n });\n } else {\n console.log(`Runtime process ${pid} is not running. Stale runtime files cleaned.`);\n }\n process.exit(1);\n }\n\n const terminated = await terminateProcess(pid);\n if (!terminated) {\n if (asJson) {\n printJsonError({\n code: 'RUNTIME_STOP_FAILED',\n message: `Failed to terminate runtime process ${pid}.`,\n recoverable: true,\n suggestion: `Try stopping PID ${pid} manually and rerun runtime stop.`,\n });\n } else {\n console.log(`Failed to terminate runtime process ${pid}.`);\n }\n process.exit(1);\n }\n\n removeRuntimeFiles(config.dataDir);\n if (asJson) {\n printJsonSuccess({ stopped: true, pid });\n } else {\n console.log(`Runtime stopped (PID: ${pid})`);\n }\n });\n\n return runtime;\n}\n","export function parseIntegerOption(value: string | undefined, name: string): number | undefined {\n if (value === undefined) {\n return undefined;\n }\n const parsed = Number.parseInt(value, 10);\n if (!Number.isInteger(parsed) || parsed <= 0) {\n throw new Error(`Invalid ${name}: ${value}. Expected positive integer.`);\n }\n return parsed;\n}\n\nexport function parseBoolOption(value: string | undefined, name: string): boolean | undefined {\n if (value === undefined) {\n return undefined;\n }\n const normalized = value.toLowerCase();\n if (normalized === 'true') return true;\n if (normalized === 'false') return false;\n throw new Error(`Invalid ${name}: ${value}. Expected true|false.`);\n}\n","import { Command } from 'commander';\nimport { CLI_COMMIT, CLI_VERSION } from '../lib/build-info.js';\nimport { printJsonSuccess } from '../lib/format.js';\n\nexport function createVersionCommand(): Command {\n return new Command('version')\n .description('Show CLI version and commit id')\n .option('--json', 'Output JSON')\n .action((options: { json?: boolean }) => {\n const payload = {\n version: CLI_VERSION,\n commit: CLI_COMMIT,\n };\n\n if (options.json) {\n printJsonSuccess(payload);\n return;\n }\n\n console.log(`Version: ${payload.version}`);\n console.log(`Commit: ${payload.commit}`);\n });\n}\n","export const CLI_VERSION = process.env.FIBER_PAY_CLI_VERSION ?? 'unknown';\nexport const CLI_COMMIT = process.env.FIBER_PAY_CLI_COMMIT ?? 'unknown';\n","import { Command } from 'commander';\nimport type { CliConfig } from '../lib/config.js';\nimport { runWalletAddressCommand } from '../lib/wallet-address.js';\nimport { runWalletBalanceCommand } from '../lib/wallet-balance.js';\n\nexport function createWalletCommand(config: CliConfig): Command {\n const wallet = new Command('wallet').description('Wallet management');\n\n wallet\n .command('address')\n .description('Display the funding address')\n .option('--json')\n .action(async (options) => {\n await runWalletAddressCommand(config, options);\n });\n\n wallet\n .command('balance')\n .description('Display the CKB balance')\n .option('--json')\n .action(async (options) => {\n await runWalletBalanceCommand(config, options);\n });\n\n return wallet;\n}\n","import { scriptToAddress } from '@fiber-pay/sdk';\nimport type { CliConfig } from './config.js';\nimport { printJsonSuccess } from './format.js';\nimport { createReadyRpcClient } from './rpc.js';\n\nexport interface WalletAddressOptions {\n json?: boolean;\n}\n\nexport async function runWalletAddressCommand(\n config: CliConfig,\n options: WalletAddressOptions,\n): Promise<void> {\n const rpc = await createReadyRpcClient(config);\n const nodeInfo = await rpc.nodeInfo();\n\n const address = scriptToAddress(\n nodeInfo.default_funding_lock_script,\n config.network === 'mainnet' ? 'mainnet' : 'testnet',\n );\n\n if (options.json) {\n printJsonSuccess({ address });\n return;\n }\n\n console.log('✅ Funding address retrieved');\n console.log(` Address: ${address}`);\n}\n","import type { CliConfig } from './config.js';\nimport { formatShannonsAsCkb, printJsonSuccess } from './format.js';\nimport { getLockBalanceShannons } from './node-rpc.js';\nimport { createReadyRpcClient } from './rpc.js';\n\nexport interface WalletBalanceOptions {\n json?: boolean;\n}\n\nexport async function runWalletBalanceCommand(\n config: CliConfig,\n options: WalletBalanceOptions,\n): Promise<void> {\n if (!config.ckbRpcUrl) {\n throw new Error(\n 'CKB RPC URL is not configured. Set FIBER_CKB_RPC_URL or add ckb.rpc_url to config.yml.',\n );\n }\n\n const rpc = await createReadyRpcClient(config);\n const nodeInfo = await rpc.nodeInfo();\n\n // Get CKB balance using the funding lock script\n const balanceShannons = await getLockBalanceShannons(\n config.ckbRpcUrl,\n nodeInfo.default_funding_lock_script,\n );\n\n // Convert shannons to CKB using BigInt-safe string formatting.\n const balanceCkb = formatShannonsAsCkb(balanceShannons, 8);\n\n if (options.json) {\n printJsonSuccess({\n balance_ckb: balanceCkb,\n balance_shannons: balanceShannons.toString(),\n });\n return;\n }\n\n console.log('✅ CKB balance retrieved');\n console.log(` Balance: ${balanceCkb} CKB`);\n console.log(` Balance (shannons): ${balanceShannons.toString()}`);\n}\n","const GLOBAL_OPTIONS_WITH_VALUE = new Set([\n '--profile',\n '--data-dir',\n '--rpc-url',\n '--network',\n '--key-password',\n '--binary-path',\n]);\n\nfunction isOptionToken(token: string): boolean {\n return token.startsWith('-') && token !== '-';\n}\n\nfunction hasInlineValue(token: string): boolean {\n return token.includes('=');\n}\n\nfunction getFirstPositional(argv: string[]): string | undefined {\n for (let index = 2; index < argv.length; index++) {\n const token = argv[index];\n\n if (token === '--') {\n return argv[index + 1];\n }\n\n if (!isOptionToken(token)) {\n return token;\n }\n\n if (GLOBAL_OPTIONS_WITH_VALUE.has(token) && !hasInlineValue(token)) {\n const next = argv[index + 1];\n if (next && !isOptionToken(next)) {\n index++;\n }\n }\n }\n\n return undefined;\n}\n\nfunction hasTopLevelVersionFlag(argv: string[]): boolean {\n for (let index = 2; index < argv.length; index++) {\n const token = argv[index];\n if (token === '--') {\n return false;\n }\n if (token === '--version' || token === '-v') {\n return true;\n }\n }\n return false;\n}\n\nexport function isTopLevelVersionRequest(argv: string[]): boolean {\n return !getFirstPositional(argv) && hasTopLevelVersionFlag(argv);\n}\n"],"mappings":"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","names":["join","Command","binaryPath","installDir","ckbToShannons","Command","resolve","existsSync","join","existsSync","readFileSync","unlinkSync","writeFileSync","join","shannonsToCkb","shannonsToCkb","Command","ckbToShannons","payload","existsSync","readFileSync","writeFileSync","Command","existsSync","readFileSync","writeFileSync","join","join","existsSync","readFileSync","writeFileSync","explicitFlags","lowered","existsSync","readFileSync","Command","writeFileSync","shannonsToCkb","toHex","Command","shannonsToCkb","Command","toHex","ckbToShannons","shannonsToCkb","toHex","Command","Command","ckbToShannons","toHex","result","payload","shannonsToCkb","output","existsSync","Command","existsSync","mkdirSync","join","dir","Command","existsSync","existsSync","statSync","join","Command","DATE_DIR_PATTERN","Command","join","date","existsSync","statSync","resolve","Command","shannonsToCkb","toHex","toHex","shannonsToCkb","mkdirSync","join","existsSync","readFileSync","dirname","BinaryManager","dirname","BinaryManager","spawnSync","spawnSync","resolve","join","mkdirSync","resolve","existsSync","ChannelState","existsSync","ChannelState","resolve","BinaryManager","MigrationManager","BinaryManager","MigrationManager","showProgress","Command","ckbToShannons","shannonsToCkb","Command","Command","ckbToShannons","payload","shannonsToCkb","Command","resolve","Command","spawn","join","formatRuntimeAlert","startRuntimeService","Command","formatRuntimeAlert","Command","spawn","runtime","startRuntimeService","join","Command","Command","Command","scriptToAddress","scriptToAddress","Command","join","Command"]}
|