#!/usr/bin/env ruby require 'lnd/tool' require 'thor' require 'yaml' require 'terminal-table' # CLI class of lnd-tool class CLI < Thor class << self def exit_on_failure? true end end desc 'capture_htlc --config "Path to configuration file"', 'Capture the HTLC events of LND.' option :config, required: true, type: :string def capture_htlc raise Thor::Error, "config file #{options['config']} does not exist." unless File.exist?(options['config']) raise Thor::Error, 'Capture process already running.' if LND::Tool::Daemon.running? config = YAML.load_file(options['config']) LND::Tool::Daemon.start do capture = LND::Tool::HTLCEventCapture.new(config['lnd']) capture.start end end desc 'stop_capture', 'Stop capture process.' def stop_capture raise Thor::Error, 'Capture process not running.' unless LND::Tool::Daemon.running? LND::Tool::Daemon.stop end desc 'query_htlc', 'Query the captured data in SQLite DB.' option :event, type: :string, desc: 'Targets the specified type of event. Valid type are "send", "receive", "forward".' option :limit, type: :numeric, desc: 'Maximum number of data' def query_htlc if options['event'] && !%w[send receive forward].include?(options['event']) raise Thor::Error, 'event must be specified as send, receive, or forward.' end headers = [ 'incoming channel', 'incoming htlc', 'outgoing channel', 'outgoing htlc', 'timestamp', 'event type', 'result', 'detail', 'incoming msat', 'outgoing msat' ] store = LND::Tool::Store::HTLCEvent.new rows = store.query(event_type: options['event']&.upcase, limit: options['limit']).map do |r| result, detail, htlc = if r.forward_event ['FORWARD', nil, r.forward_event.info] elsif r.forward_fail_event ['FORWARD FAIL'] elsif r.settle_event ['SETTLE'] elsif r.link_fail_event ['LINK_FAIL', r.link_fail_event.wire_failure, r.link_fail_event.info] end [ { value: r.incoming_channel_id, alignment: :right }, { value: r.incoming_htlc_id, alignment: :right }, { value: r.outgoing_channel_id, alignment: :right }, { value: r.outgoing_htlc_id, alignment: :right }, Time.at(r.timestamp_ns / 1000000000), r.event_type, result, detail, { value: htlc&.incoming_amt_msat, alignment: :right }, { value: htlc&.outgoing_amt_msat, alignment: :right } ] end table = Terminal::Table.new(title: 'HTLC Events', headings: headers, rows: rows) puts table end end CLI.start(ARGV)