@fiber-pay/cli 0.1.0-rc.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/commands/binary.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/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-runtime-daemon.ts","../src/lib/node-start.ts","../src/lib/bootnode.ts","../src/lib/node-status.ts","../src/lib/node-recommendation.ts","../src/lib/node-rpc.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"],"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 { 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 '--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 applyGlobalOverrides(process.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 .version(`${CLI_VERSION} (${CLI_COMMIT})`, '-v, --version', 'Show version and commit id')\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('--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(process.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 {\n DEFAULT_FIBER_VERSION,\n type DownloadProgress,\n downloadFiberBinary,\n getFiberBinaryInfo,\n} from '@fiber-pay/node';\nimport { Command } from 'commander';\nimport type { CliConfig } from '../lib/config.js';\nimport { 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 info = await downloadFiberBinary({\n installDir: `${config.dataDir}/bin`,\n version: options.version,\n force: Boolean(options.force),\n onProgress: options.json ? undefined : showProgress,\n });\n\n if (options.json) {\n printJsonSuccess(info);\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 info = await getFiberBinaryInfo(`${config.dataDir}/bin`);\n\n if (options.json) {\n printJsonSuccess(info);\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 {\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\nexport function printNodeInfoHuman(data: {\n nodeId: string;\n addresses: string[];\n chainHash: string;\n fundingAddress: string;\n version: string;\n channelCount: number;\n pendingChannelCount: number;\n peersCount: number;\n}): void {\n console.log('Node Info');\n console.log(` Node ID: ${data.nodeId}`);\n console.log(` Version: ${data.version}`);\n console.log(` Chain Hash: ${data.chainHash}`);\n console.log(` Funding Address: ${data.fundingAddress}`);\n console.log(` Channels: ${data.channelCount} (${data.pendingChannelCount} pending)`);\n console.log(` Peers: ${data.peersCount}`);\n if (data.addresses.length > 0) {\n console.log(' Addresses:');\n for (const addr of data.addresses) {\n console.log(` - ${addr}`);\n }\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';\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: false,\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 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({ url: resolved.url });\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 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 { 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 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 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 // 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 keyPassword,\n ckbRpcUrl,\n runtimeProxyListen,\n },\n sources: {\n dataDir: dataDirSource,\n configPath: 'derived',\n network: networkSource,\n rpcUrl: rpcUrlSource,\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_V061 = `# 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/127.0.0.1/tcp/8228\"\n bootnode_addrs:\n - \"/ip4/54.179.226.154/tcp/8228/p2p/Qmes1EBD4yNo9Ywkfe6eRw9tG1nVNGLDmMud1xJMsoYFKy\"\n - \"/ip4/54.179.226.154/tcp/18228/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_V061 = `# 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_V061 : TESTNET_CONFIG_TEMPLATE_V061;\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('--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\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 const logPaths = resolvePersistedLogPaths(config.dataDir, meta);\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 { existsSync, readFileSync } 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\nexport function resolvePersistedLogPaths(\n dataDir: string,\n meta?: RuntimeMeta | null,\n): PersistedLogPaths {\n return {\n runtimeAlerts: meta?.alertLogFilePath ?? join(dataDir, 'logs', 'runtime.alerts.jsonl'),\n fnnStdout: meta?.fnnStdoutLogPath ?? join(dataDir, 'logs', 'fnn.stdout.log'),\n fnnStderr: meta?.fnnStderrLogPath ?? join(dataDir, 'logs', 'fnn.stderr.log'),\n };\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 const content = readFileSync(filePath, 'utf-8');\n const lines = content.split(/\\r?\\n/).filter((line) => line.length > 0);\n return lines.slice(-maxLines);\n}\n","import { existsSync } from 'node:fs';\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 type PersistedLogSourceOption,\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]);\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('--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 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 const meta = readRuntimeMeta(config.dataDir);\n const paths = resolvePersistedLogPaths(config.dataDir, meta);\n const targets = resolvePersistedLogTargets(paths, source);\n\n if (source !== 'all' && targets.length === 1 && !existsSync(targets[0].path)) {\n const message = `Log file not found for source ${source}: ${targets[0].path}`;\n if (json) {\n printJsonError({\n code: 'LOG_FILE_NOT_FOUND',\n message,\n recoverable: true,\n suggestion: 'Start node/runtime or generate activity, then retry logs command.',\n details: { source, 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 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 console.log(`Logs (source: ${source}, 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 seenLines: entry.exists ? entry.lines.length : 0,\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 const timer = setInterval(() => {\n for (const target of targets) {\n const state = states.get(target.source);\n if (!state) continue;\n\n if (!existsSync(state.path)) {\n continue;\n }\n\n const allLines = readLastLines(state.path, Number.MAX_SAFE_INTEGER);\n const total = allLines.length;\n const fromIndex = total < state.seenLines ? 0 : state.seenLines;\n const newLines = allLines.slice(fromIndex);\n if (newLines.length === 0) {\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.seenLines = total;\n }\n }, intervalMs);\n\n process.on('SIGINT', stop);\n process.on('SIGTERM', stop);\n });\n });\n}\n","import { nodeIdToPeerId, scriptToAddress } from '@fiber-pay/sdk';\nimport { Command } from 'commander';\nimport type { CliConfig } from '../lib/config.js';\nimport { printJsonError, printJsonSuccess, printNodeInfoHuman } from '../lib/format.js';\nimport { stopRuntimeDaemonFromNode } from '../lib/node-runtime-daemon.js';\nimport { runNodeStartCommand } from '../lib/node-start.js';\nimport { runNodeReadyCommand, runNodeStatusCommand } from '../lib/node-status.js';\nimport { isProcessRunning, readPidFile, removePidFile } from '../lib/pid.js';\nimport { createReadyRpcClient } from '../lib/rpc.js';\nimport { readRuntimeMeta, readRuntimePid, removeRuntimeFiles } from '../lib/runtime-meta.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 const json = Boolean(options.json);\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 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 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 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('info')\n .option('--json')\n .action(async (options) => {\n const rpc = await createReadyRpcClient(config);\n const nodeInfo = await rpc.nodeInfo();\n const fundingAddress = scriptToAddress(nodeInfo.default_funding_lock_script, config.network);\n const peerId = await nodeIdToPeerId(nodeInfo.node_id);\n const output = {\n nodeId: nodeInfo.node_id,\n peerId,\n addresses: nodeInfo.addresses,\n chainHash: nodeInfo.chain_hash,\n fundingAddress,\n fundingLockScript: nodeInfo.default_funding_lock_script,\n version: nodeInfo.version,\n channelCount: parseInt(nodeInfo.channel_count, 16),\n pendingChannelCount: parseInt(nodeInfo.pending_channel_count, 16),\n peersCount: parseInt(nodeInfo.peers_count, 16),\n };\n\n if (options.json) {\n printJsonSuccess(output);\n } else {\n printNodeInfoHuman(output);\n }\n });\n\n return node;\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 alertLogFile: 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-log-file',\n params.alertLogFile,\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 { spawn } from 'node:child_process';\nimport { appendFileSync, mkdirSync } from 'node:fs';\nimport { join } from 'node:path';\nimport {\n ensureFiberBinary,\n type FiberNodeConfig,\n getDefaultBinaryPath,\n ProcessManager,\n} from '@fiber-pay/node';\nimport { startRuntimeService } from '@fiber-pay/runtime';\nimport { createKeyManager } from '@fiber-pay/sdk';\nimport { autoConnectBootnodes, extractBootnodeAddrs } from './bootnode.js';\nimport { type CliConfig, ensureNodeConfigFile } from './config.js';\nimport { printJsonError, printJsonEvent } from './format.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';\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 logsDir = join(config.dataDir, 'logs');\n const fnnStdoutLogPath = join(logsDir, 'fnn.stdout.log');\n const fnnStderrLogPath = join(logsDir, 'fnn.stderr.log');\n const runtimeAlertLogPath = join(logsDir, 'runtime.alerts.jsonl');\n mkdirSync(logsDir, { recursive: true });\n\n const binaryPath = config.binaryPath || getDefaultBinaryPath();\n await ensureFiberBinary();\n const binaryVersion = getBinaryVersion(binaryPath);\n const configFilePath = ensureNodeConfigFile(config.dataDir, config.network);\n emitStage('binary_resolved', 'ok', {\n binaryPath,\n binaryVersion,\n configFilePath,\n });\n\n if (!json) {\n console.log(`🧩 Binary: ${binaryPath}`);\n console.log(`🧩 Version: ${binaryVersion}`);\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 appendFileSync(fnnStdoutLogPath, text, 'utf-8');\n emitFnnLog('stdout', text);\n });\n processManager.on('stderr', (text) => {\n appendFileSync(fnnStderrLogPath, text, 'utf-8');\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 if (runtimeDaemon) {\n const daemonStart = startRuntimeDaemonFromNode({\n dataDir: config.dataDir,\n rpcUrl: config.rpcUrl,\n proxyListen: runtimeProxyListen,\n stateFilePath: runtimeStateFilePath,\n alertLogFile: runtimeAlertLogPath,\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: 'file', path: runtimeAlertLogPath }],\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 writeRuntimeMeta(config.dataDir, {\n pid: process.pid,\n startedAt: runtimeStatus.startedAt,\n fiberRpcUrl: runtimeStatus.targetUrl,\n proxyListen: runtimeStatus.proxyListen,\n stateFilePath: runtimeStateFilePath,\n alertLogFilePath: runtimeAlertLogPath,\n fnnStdoutLogPath,\n fnnStderrLogPath,\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 fnnStdout: fnnStdoutLogPath,\n fnnStderr: fnnStderrLogPath,\n runtimeAlerts: runtimeAlertLogPath,\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: ${logsDir}`);\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","import { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { getFiberBinaryInfo } from '@fiber-pay/node';\nimport {\n buildMultiaddrFromNodeId,\n buildMultiaddrFromRpcUrl,\n ChannelState,\n nodeIdToPeerId,\n type Script,\n scriptToAddress,\n} from '@fiber-pay/sdk';\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 { getCustomBinaryState } from './node-runtime-daemon.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 managedBinaryPath = join(config.dataDir, 'bin', 'fnn');\n const binaryInfo = config.binaryPath\n ? getCustomBinaryState(config.binaryPath)\n : await getFiberBinaryInfo(join(config.dataDir, 'bin'));\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 peerId: string | null = null;\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 canSend = false;\n let canReceive = false;\n let localCkb = 0;\n let remoteCkb = 0;\n let fundingAddress: string | 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 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 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 if (config.ckbRpcUrl) {\n try {\n const fundingBalance = await getLockBalanceShannons(\n config.ckbRpcUrl,\n nodeInfo.default_funding_lock_script as Script,\n );\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 peerId,\n peerIdError,\n multiaddr,\n multiaddrError,\n multiaddrInferred,\n checks: {\n binary: {\n path: binaryInfo.path,\n ready: binaryInfo.ready,\n version: binaryInfo.version,\n source: config.binaryPath ? 'env-binary-path' : 'managed-binary-dir',\n managedPath: managedBinaryPath,\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 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.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 } 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(` 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.total} ready/total`,\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","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';\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 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('--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 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 { 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 { 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';\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\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')\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\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 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: String(options.proxyListen ?? config.runtimeProxyListen ?? '127.0.0.1:8229'),\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 const alertLogFile = options.alertLogFile\n ? resolve(String(options.alertLogFile))\n : resolve(config.dataDir, 'logs', 'runtime.alerts.jsonl');\n\n const alerts: RuntimeConfigInput['alerts'] = [{ type: 'stdout' }];\n alerts.push({ type: 'file', path: alertLogFile });\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 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: alertLogFile,\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,\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(`Alert log: ${alertLogFile}`);\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 const pid = readRuntimePid(config.dataDir);\n const meta = readRuntimeMeta(config.dataDir);\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) {\n try {\n const response = await fetch(`http://${meta.proxyListen}/monitor/status`);\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 const pid = readRuntimePid(config.dataDir);\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 process.kill(pid, 'SIGTERM');\n\n let attempts = 0;\n while (isProcessRunning(pid) && attempts < 50) {\n await new Promise((resolve) => setTimeout(resolve, 100));\n attempts += 1;\n }\n\n if (isProcessRunning(pid)) {\n process.kill(pid, 'SIGKILL');\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"],"mappings":"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","names":["join","Command","Command","resolve","existsSync","readFileSync","unlinkSync","writeFileSync","join","Command","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","readFileSync","join","Command","existsSync","existsSync","Command","Command","existsSync","resolve","nodeIdToPeerId","scriptToAddress","Command","existsSync","mkdirSync","join","existsSync","readFileSync","join","mkdirSync","resolve","existsSync","join","getFiberBinaryInfo","ChannelState","join","getFiberBinaryInfo","existsSync","ChannelState","Command","resolve","scriptToAddress","nodeIdToPeerId","ckbToShannons","shannonsToCkb","Command","Command","ckbToShannons","payload","shannonsToCkb","Command","resolve","Command","spawn","formatRuntimeAlert","startRuntimeService","Command","formatRuntimeAlert","Command","spawn","runtime","startRuntimeService","resolve","Command","Command","join","Command"]}