feat(console): lite backend command-reference modal

Give the lite console the parity analog of the full-node RPC command
reference: the same searchable two-pane modal (browse/search, detail
pane, examples, Insert / Insert & run, destructive confirm), driven by
the lite backend's own command set instead of daemon RPC.

- ConsoleCommandExecutor::commandReference() returns the category table
  (full node = consoleCommandCategories(); lite = new
  liteConsoleCommandCategories() -- 25 backend verbs in 5 categories).
  The shared renderCommandsPopup reads the table from the executor.
- The Commands button now shows for both variants (gated on
  commandReference()!=nullptr); title/tooltip/arg-quoting branch on
  hasRpcReference() (clarified to mean "speaks JSON-RPC / full node").
- Lite args are bare tokens (the backend takes one unsplit arg string
  and does not strip quotes), so the param-builder's JSON string
  auto-quoting is disabled for lite -- Insert & run emits runnable bare
  commands. send uses the JSON-array form (its positional form is
  unreachable via the single-arg transport); new uses zs/R; import
  takes just the key (the backend hardcodes birthday=0).

Adds 7 i18n keys across all 8 languages (additive). Full-node behavior
is unchanged. Adversarially reviewed (data vs the backend registry,
plumbing/regression, i18n) with all findings fixed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-19 12:27:51 -05:00
parent 567732206e
commit 5c570613c8
16 changed files with 248 additions and 23 deletions

View File

@@ -271,13 +271,18 @@
"console_app": "App",
"console_auto_scroll": "Automatisch scrollen",
"console_available_commands": "Verfügbare Befehle:",
"console_backend_reference": "Backend-Befehlsreferenz",
"console_backend_unavailable": "Kein Backend",
"console_capturing_output": "Erfasse Daemon-Ausgabe...",
"console_cat_advanced": "Erweitert",
"console_cat_blockchain": "Blockchain",
"console_cat_control": "Steuerung",
"console_cat_keys": "Schlüssel & Sicherheit",
"console_cat_mining": "Mining",
"console_cat_network": "Netzwerk",
"console_cat_raw_transactions": "Rohtransaktionen",
"console_cat_send": "Senden",
"console_cat_sync": "Synchronisierung",
"console_cat_utility": "Dienstprogramme",
"console_cat_wallet": "Wallet",
"console_clear": "Leeren",
@@ -334,12 +339,14 @@
"console_ref_run_confirm": "%s jetzt ausführen? Dies ist ein folgenreicher Befehl.",
"console_ref_search_hint": "Nach Name oder Aufgabe suchen…",
"console_ref_select_hint": "Wählen Sie einen Befehl, um zu sehen, was er tut.",
"console_ref_value": "Wert",
"console_rpc_reference": "RPC-Befehlsreferenz",
"console_rpc_trace": "RPC",
"console_scanline": "Konsolen-Scanline",
"console_search_commands": "Befehle suchen...",
"console_select_all": "Alles auswählen",
"console_show_app_output": "[App]-Wallet-Protokollzeilen anzeigen",
"console_show_backend_ref": "Backend-Befehlsreferenz anzeigen",
"console_show_daemon_output": "Daemon-Ausgabe anzeigen",
"console_show_errors_only": "Nur Fehler anzeigen",
"console_show_rpc_ref": "RPC-Befehlsreferenz anzeigen",

View File

@@ -271,13 +271,18 @@
"console_app": "App",
"console_auto_scroll": "Auto-desplazamiento",
"console_available_commands": "Comandos disponibles:",
"console_backend_reference": "Referencia de Comandos del Backend",
"console_backend_unavailable": "Sin backend",
"console_capturing_output": "Capturando salida del daemon...",
"console_cat_advanced": "Avanzado",
"console_cat_blockchain": "Blockchain",
"console_cat_control": "Control",
"console_cat_keys": "Claves y seguridad",
"console_cat_mining": "Minería",
"console_cat_network": "Red",
"console_cat_raw_transactions": "Transacciones sin procesar",
"console_cat_send": "Enviar",
"console_cat_sync": "Sincronización",
"console_cat_utility": "Utilidades",
"console_cat_wallet": "Cartera",
"console_clear": "Limpiar",
@@ -334,12 +339,14 @@
"console_ref_run_confirm": "¿Ejecutar %s ahora? Es un comando con consecuencias.",
"console_ref_search_hint": "Buscar por nombre o tarea…",
"console_ref_select_hint": "Selecciona un comando para ver qué hace.",
"console_ref_value": "valor",
"console_rpc_reference": "Referencia de Comandos RPC",
"console_rpc_trace": "RPC",
"console_scanline": "Líneas de consola",
"console_search_commands": "Buscar comandos...",
"console_select_all": "Seleccionar Todo",
"console_show_app_output": "Mostrar las líneas de registro de la cartera [app]",
"console_show_backend_ref": "Mostrar referencia de comandos del backend",
"console_show_daemon_output": "Mostrar salida del daemon",
"console_show_errors_only": "Mostrar solo errores",
"console_show_rpc_ref": "Mostrar referencia de comandos RPC",

View File

@@ -271,13 +271,18 @@
"console_app": "App",
"console_auto_scroll": "Défilement auto",
"console_available_commands": "Commandes disponibles :",
"console_backend_reference": "Référence des commandes du backend",
"console_backend_unavailable": "Aucun backend",
"console_capturing_output": "Capture de la sortie du daemon...",
"console_cat_advanced": "Avancé",
"console_cat_blockchain": "Blockchain",
"console_cat_control": "Contrôle",
"console_cat_keys": "Clés et sécurité",
"console_cat_mining": "Minage",
"console_cat_network": "Réseau",
"console_cat_raw_transactions": "Transactions brutes",
"console_cat_send": "Envoyer",
"console_cat_sync": "Synchronisation",
"console_cat_utility": "Utilitaires",
"console_cat_wallet": "Portefeuille",
"console_clear": "Effacer",
@@ -334,12 +339,14 @@
"console_ref_run_confirm": "Exécuter %s maintenant ? C'est une commande à conséquences.",
"console_ref_search_hint": "Rechercher par nom ou tâche…",
"console_ref_select_hint": "Sélectionnez une commande pour voir ce qu'elle fait.",
"console_ref_value": "valeur",
"console_rpc_reference": "Référence des commandes RPC",
"console_rpc_trace": "RPC",
"console_scanline": "Scanline de la console",
"console_search_commands": "Rechercher des commandes...",
"console_select_all": "Tout sélectionner",
"console_show_app_output": "Afficher les lignes du journal du portefeuille [app]",
"console_show_backend_ref": "Afficher la référence des commandes du backend",
"console_show_daemon_output": "Afficher la sortie du daemon",
"console_show_errors_only": "Afficher uniquement les erreurs",
"console_show_rpc_ref": "Afficher la référence des commandes RPC",

View File

@@ -271,13 +271,18 @@
"console_app": "アプリ",
"console_auto_scroll": "自動スクロール",
"console_available_commands": "利用可能なコマンド:",
"console_backend_reference": "バックエンドコマンドリファレンス",
"console_backend_unavailable": "バックエンドなし",
"console_capturing_output": "デーモン出力をキャプチャ中...",
"console_cat_advanced": "詳細設定",
"console_cat_blockchain": "ブロックチェーン",
"console_cat_control": "制御",
"console_cat_keys": "鍵とセキュリティ",
"console_cat_mining": "マイニング",
"console_cat_network": "ネットワーク",
"console_cat_raw_transactions": "生トランザクション",
"console_cat_send": "送金",
"console_cat_sync": "同期",
"console_cat_utility": "ユーティリティ",
"console_cat_wallet": "ウォレット",
"console_clear": "クリア",
@@ -334,12 +339,14 @@
"console_ref_run_confirm": "%s を今すぐ実行しますか? 影響の大きいコマンドです。",
"console_ref_search_hint": "名前または用途で検索…",
"console_ref_select_hint": "コマンドを選ぶと内容が表示されます。",
"console_ref_value": "値",
"console_rpc_reference": "RPCコマンドリファレンス",
"console_rpc_trace": "RPC",
"console_scanline": "コンソールスキャンライン",
"console_search_commands": "コマンドを検索...",
"console_select_all": "すべて選択",
"console_show_app_output": "[app] ウォレットのログ行を表示",
"console_show_backend_ref": "バックエンドコマンドリファレンスを表示",
"console_show_daemon_output": "デーモン出力を表示",
"console_show_errors_only": "エラーのみ表示",
"console_show_rpc_ref": "RPCコマンドリファレンスを表示",

View File

@@ -271,13 +271,18 @@
"console_app": "앱",
"console_auto_scroll": "자동 스크롤",
"console_available_commands": "사용 가능한 명령어:",
"console_backend_reference": "백엔드 명령어 참조",
"console_backend_unavailable": "백엔드 없음",
"console_capturing_output": "데몬 출력 캡처 중...",
"console_cat_advanced": "고급",
"console_cat_blockchain": "블록체인",
"console_cat_control": "제어",
"console_cat_keys": "키 및 보안",
"console_cat_mining": "채굴",
"console_cat_network": "네트워크",
"console_cat_raw_transactions": "원시 트랜잭션",
"console_cat_send": "보내기",
"console_cat_sync": "동기화",
"console_cat_utility": "유틸리티",
"console_cat_wallet": "지갑",
"console_clear": "지우기",
@@ -334,12 +339,14 @@
"console_ref_run_confirm": "%s 을(를) 지금 실행할까요? 영향이 큰 명령입니다.",
"console_ref_search_hint": "이름 또는 용도로 검색…",
"console_ref_select_hint": "명령을 선택하면 설명이 표시됩니다.",
"console_ref_value": "값",
"console_rpc_reference": "RPC 명령어 참조",
"console_rpc_trace": "RPC",
"console_scanline": "콘솔 스캔라인",
"console_search_commands": "명령어 검색...",
"console_select_all": "모두 선택",
"console_show_app_output": "[app] 지갑 로그 줄 표시",
"console_show_backend_ref": "백엔드 명령어 참조 표시",
"console_show_daemon_output": "데몬 출력 표시",
"console_show_errors_only": "오류만 표시",
"console_show_rpc_ref": "RPC 명령어 참조 표시",

View File

@@ -271,13 +271,18 @@
"console_app": "App",
"console_auto_scroll": "Rolagem automática",
"console_available_commands": "Comandos disponíveis:",
"console_backend_reference": "Referência de Comandos do Backend",
"console_backend_unavailable": "Sem backend",
"console_capturing_output": "Capturando saída do daemon...",
"console_cat_advanced": "Avançado",
"console_cat_blockchain": "Blockchain",
"console_cat_control": "Controle",
"console_cat_keys": "Chaves e segurança",
"console_cat_mining": "Mineração",
"console_cat_network": "Rede",
"console_cat_raw_transactions": "Transações brutas",
"console_cat_send": "Enviar",
"console_cat_sync": "Sincronização",
"console_cat_utility": "Utilitários",
"console_cat_wallet": "Carteira",
"console_clear": "Limpar",
@@ -334,12 +339,14 @@
"console_ref_run_confirm": "Executar %s agora? Este é um comando com consequências.",
"console_ref_search_hint": "Pesquisar por nome ou tarefa…",
"console_ref_select_hint": "Selecione um comando para ver o que ele faz.",
"console_ref_value": "valor",
"console_rpc_reference": "Referência de Comandos RPC",
"console_rpc_trace": "RPC",
"console_scanline": "Scanline do console",
"console_search_commands": "Pesquisar comandos...",
"console_select_all": "Selecionar Tudo",
"console_show_app_output": "Mostrar linhas do log da carteira [app]",
"console_show_backend_ref": "Mostrar referência de comandos do backend",
"console_show_daemon_output": "Mostrar saída do daemon",
"console_show_errors_only": "Mostrar apenas erros",
"console_show_rpc_ref": "Mostrar referência de comandos RPC",

View File

@@ -271,13 +271,18 @@
"console_app": "Прил.",
"console_auto_scroll": "Авто-прокрутка",
"console_available_commands": "Доступные команды:",
"console_backend_reference": "Справочник команд бэкенда",
"console_backend_unavailable": "Нет бэкенда",
"console_capturing_output": "Захват вывода daemon...",
"console_cat_advanced": "Дополнительно",
"console_cat_blockchain": "Блокчейн",
"console_cat_control": "Управление",
"console_cat_keys": "Ключи и безопасность",
"console_cat_mining": "Майнинг",
"console_cat_network": "Сеть",
"console_cat_raw_transactions": "Сырые транзакции",
"console_cat_send": "Отправка",
"console_cat_sync": "Синхронизация",
"console_cat_utility": "Утилиты",
"console_cat_wallet": "Кошелёк",
"console_clear": "Очистить",
@@ -334,12 +339,14 @@
"console_ref_run_confirm": "Выполнить %s сейчас? Это ответственная команда.",
"console_ref_search_hint": "Поиск по названию или задаче…",
"console_ref_select_hint": "Выберите команду, чтобы увидеть, что она делает.",
"console_ref_value": "значение",
"console_rpc_reference": "Справочник RPC-команд",
"console_rpc_trace": "RPC",
"console_scanline": "Скан-линия консоли",
"console_search_commands": "Поиск команд...",
"console_select_all": "Выбрать всё",
"console_show_app_output": "Показать строки журнала кошелька [app]",
"console_show_backend_ref": "Показать справочник команд бэкенда",
"console_show_daemon_output": "Показать вывод daemon",
"console_show_errors_only": "Показать только ошибки",
"console_show_rpc_ref": "Показать справочник RPC-команд",

View File

@@ -271,13 +271,18 @@
"console_app": "应用",
"console_auto_scroll": "自动滚动",
"console_available_commands": "可用命令:",
"console_backend_reference": "后端命令参考",
"console_backend_unavailable": "无后端",
"console_capturing_output": "正在捕获守护进程输出...",
"console_cat_advanced": "高级",
"console_cat_blockchain": "区块链",
"console_cat_control": "控制",
"console_cat_keys": "密钥与安全",
"console_cat_mining": "挖矿",
"console_cat_network": "网络",
"console_cat_raw_transactions": "原始交易",
"console_cat_send": "发送",
"console_cat_sync": "同步",
"console_cat_utility": "实用工具",
"console_cat_wallet": "钱包",
"console_clear": "清除",
@@ -334,12 +339,14 @@
"console_ref_run_confirm": "立即运行 %s这是一个有重大影响的命令。",
"console_ref_search_hint": "按名称或用途搜索…",
"console_ref_select_hint": "选择一个命令以查看其功能。",
"console_ref_value": "值",
"console_rpc_reference": "RPC 命令参考",
"console_rpc_trace": "RPC",
"console_scanline": "控制台扫描线",
"console_search_commands": "搜索命令...",
"console_select_all": "全选",
"console_show_app_output": "显示[应用]钱包日志行",
"console_show_backend_ref": "显示后端命令参考",
"console_show_daemon_output": "显示守护进程输出",
"console_show_errors_only": "仅显示错误",
"console_show_rpc_ref": "显示 RPC 命令参考",

View File

@@ -2005,8 +2005,8 @@ void App::render()
// Send confirm popup
ui::RenderSendConfirmPopup(this);
// Console RPC Command Reference popup
console_tab_.renderCommandsPopupModal();
// Console command-reference popup (full-node RPC reference / lite backend verbs).
console_tab_.renderCommandsPopupModal(console_exec_.get());
// Key export dialog (triggered from balance tab context menu)
ui::KeyExportDialog::render(this);

View File

@@ -4,6 +4,7 @@
#include "console_command_executor.h"
#include "console_channel.h"
#include "console_command_reference.h" // consoleCommandCategories / liteConsoleCommandCategories
#include "console_input_model.h" // BuildConsoleRpcCall
#include "../../app.h"
@@ -194,6 +195,11 @@ void FullNodeConsoleExecutor::printHelp(const ConsoleAddLineFn& add)
add(TR("console_tab_completion"), ConsoleChannel::Info);
}
const std::vector<ConsoleCommandCategory>* FullNodeConsoleExecutor::commandReference() const
{
return &consoleCommandCategories();
}
ConsoleStatusLine FullNodeConsoleExecutor::toolbarStatus() const
{
ConsoleStatusLine s;
@@ -293,6 +299,12 @@ void LiteConsoleExecutor::printHelp(const ConsoleAddLineFn& add)
add(" sync syncstatus balance addresses height info list notes encryptionstatus", ConsoleChannel::None);
add(" send shield new seed import timport export", ConsoleChannel::None);
add(" encrypt decrypt lock unlock rescan save sietch saplingtree coinsupply", ConsoleChannel::None);
add(TR("console_click_commands"), ConsoleChannel::Info);
}
const std::vector<ConsoleCommandCategory>* LiteConsoleExecutor::commandReference() const
{
return &liteConsoleCommandCategories();
}
std::vector<ConsoleStatusLine> LiteConsoleExecutor::statusLines() const

View File

@@ -25,6 +25,8 @@ namespace dragonx {
class App;
namespace ui {
struct ConsoleCommandCategory; // console_command_reference.h — command-reference table
using ConsoleAddLineFn = std::function<void(const std::string&, ConsoleChannel)>;
struct ConsoleStatusLine {
@@ -64,7 +66,13 @@ public:
virtual void pollLogLines(const ConsoleAddLineFn& add) { (void)add; }
// UI-chrome capabilities.
virtual bool hasRpcReference() const { return false; } // show the RPC command-reference popup
// True when this backend speaks JSON-RPC to a daemon (the full node). Gates daemon-specific
// console behavior (the 'stop' shutdown confirm, "not connected to daemon" wording) and the
// command-reference modal's JSON string-arg quoting — the lite backend takes bare tokens.
virtual bool hasRpcReference() const { return false; }
// The command-reference table this backend offers (browsed by the console's reference modal),
// or nullptr for none. Full node = the JSON-RPC reference; lite = its own backend verbs.
virtual const std::vector<ConsoleCommandCategory>* commandReference() const { return nullptr; }
// Which log-filter toggles the toolbar should show (default: none).
virtual ConsoleLogFilterCaps logFilterCaps() const { return {}; }
@@ -88,6 +96,7 @@ public:
bool pollResult(std::string& result, bool& isError) override;
void pollLogLines(const ConsoleAddLineFn& add) override;
bool hasRpcReference() const override { return true; }
const std::vector<ConsoleCommandCategory>* commandReference() const override;
// Full node: daemon/xmrig log, errors-only, RPC trace, and app messages.
ConsoleLogFilterCaps logFilterCaps() const override { return {true, true, true, true}; }
void printHelp(const ConsoleAddLineFn& add) override;
@@ -119,6 +128,7 @@ public:
// Lite: no daemon log / RPC trace — its diagnostics ring maps to the App + Error
// channels, so offer errors-only + app-messages (plus the always-shown text filter).
ConsoleLogFilterCaps logFilterCaps() const override { return {false, true, false, true}; }
const std::vector<ConsoleCommandCategory>* commandReference() const override;
void printHelp(const ConsoleAddLineFn& add) override;
std::vector<ConsoleStatusLine> statusLines() const override;
ConsoleStatusLine toolbarStatus() const override;

View File

@@ -280,6 +280,105 @@ const ConsoleCommandEntry kUtilityCommands[] = {
"reconsiderblock \"0000000000abc123\"", "undo invalidate accept block again re-enable block restore chain reconsider fix rollback fork", true},
};
// ============================================================================
// Lite backend command set — the verbs the SDXL lite backend accepts (see its
// commands.rs get_commands()). Unlike the full node these are NOT JSON-RPC: the
// backend takes plain, space-separated tokens (no quoting), so the reference
// modal inserts them bare. clear/help/quit are intentionally omitted — the C++
// console tab intercepts those before they reach the backend.
// ============================================================================
const ConsoleCommandEntry kLiteWalletCommands[] = {
{"balance", "Show your DRGX balance", "",
"Shows the DRGX balance held in this wallet across all its shielded and transparent addresses.",
"balance", "money funds amount total holdings"},
{"addresses", "List all addresses in the wallet", "",
"Lists every address this wallet owns \xE2\x80\x94 shielded (zs1...) and transparent (R.../t...) \xE2\x80\x94 so you can pick one to receive to.",
"addresses", "receive address list wallet mine deposit"},
{"new", "Create a new address in this wallet", "type",
"Creates a fresh receive address. Pass zs for a shielded (private) sapling address, or R (a capital R) for a transparent one \xE2\x80\x94 those exact tokens (case-sensitive).",
"new zs", "create address receive generate new shielded transparent zs"},
{"list", "List all transactions in the wallet", "",
"Shows the wallet's transaction history \xE2\x80\x94 sends, receives and shields \xE2\x80\x94 with amounts, addresses and confirmations.",
"list", "history transactions txs payments activity sent received"},
{"notes", "List sapling notes and UTXOs", "[all]",
"Lists the individual shielded notes and transparent UTXOs that make up your balance. Pass all to include spent ones.",
"notes", "utxo notes unspent coins inputs sapling"},
{"info", "Get the lightwalletd server's info", "",
"Reports the lightwalletd server the wallet is connected to \xE2\x80\x94 its version, chain and block height.",
"info", "server node lightwalletd version connection status"},
};
const ConsoleCommandEntry kLiteSyncCommands[] = {
{"sync", "Download compact blocks and sync to the server", "",
"Fetches new compact blocks from the lightwalletd server and scans them for transactions belonging to this wallet.",
"sync", "update refresh scan blocks download catch up"},
{"syncstatus", "Get the sync status of the wallet", "",
"Reports how far the wallet has synced \xE2\x80\x94 whether a sync is in progress and the block it has reached.",
"syncstatus", "progress status syncing scanning percent blocks"},
{"height", "Get the latest block height the wallet is at", "",
"Shows the block height the wallet has scanned up to. Compare with the network height to gauge sync.",
"height", "block height number chain tip synced"},
{"rescan", "Rescan the wallet from scratch", "",
"Discards the scanned state and re-downloads/re-scans every block from the wallet's birthday. Slow, but fixes a stuck or incomplete balance.",
"rescan", "rescan resync repair fix balance rebuild from scratch"},
{"save", "Save the wallet file to disk", "",
"Writes the current wallet state to disk. The wallet also saves automatically after a sync or send.",
"save", "save persist write disk store"},
};
const ConsoleCommandEntry kLiteSendCommands[] = {
{"send", "Send DRGX to an address", "[{\"address\":\"zs1...\",\"amount\":0}]",
"Sends DRGX from the console using a JSON array of recipients (the Send tab is the easy way; this is the power-user form). amount is in puposhis (the base unit); memo is optional and delivered privately to shielded recipients.",
"send [{\"address\":\"zs1exampleaddress\",\"amount\":100000000,\"memo\":\"thanks\"}]",
"pay transfer send spend money transaction json", true},
{"shield", "Shield transparent DRGX into a sapling address", "[address]",
"Moves your transparent (public) DRGX into a shielded sapling address for privacy. With no address it shields to the wallet's own sapling address.",
"shield", "shield private sapling transparent move protect", true},
};
const ConsoleCommandEntry kLiteKeyCommands[] = {
{"seed", "Display the wallet seed phrase", "",
"Reveals the seed phrase that backs up this wallet. Anyone who sees it can spend your funds \xE2\x80\x94 keep it secret and offline.",
"seed", "seed phrase mnemonic backup recovery words secret", true},
{"export", "Export the private key for an address", "[address]",
"Prints the private/spending key for a wallet address \xE2\x80\x94 anyone with it controls the funds. With no address it exports every key.",
"export zs1exampleaddress", "export private key spending backup secret", true},
{"import", "Import a spending or viewing key", "key",
"Imports a shielded spending or viewing key (pass just the key). The wallet rescans from the sapling activation height to find the key's transactions.",
"import somekey", "import restore key spending viewing add watch"},
{"timport", "Import a transparent WIF private key", "wif",
"Imports a transparent private key in WIF format (begins with U, 5, K or L) so the wallet can spend its funds.",
"timport somewifkey", "import transparent wif private key taddr"},
{"encrypt", "Encrypt the wallet with a password", "password",
"Encrypts the wallet with a password and locks it immediately. You will need the password to send or reveal keys afterwards. If you forget it, only the seed phrase can recover the wallet.",
"encrypt strongpassword", "encrypt password protect lock secure passphrase", true},
{"decrypt", "Completely remove wallet encryption", "password",
"Permanently removes the wallet's password encryption, leaving it unprotected on disk. Requires the current password.",
"decrypt strongpassword", "decrypt remove encryption password unprotect", true},
{"unlock", "Unlock the wallet for spending", "password",
"Temporarily unlocks an encrypted wallet so it can send or reveal keys. Use lock to re-lock it.",
"unlock strongpassword", "unlock password spend open temporarily"},
{"lock", "Lock a temporarily-unlocked wallet", "",
"Re-locks a wallet that was unlocked for spending, without removing its encryption.",
"lock", "lock secure re-lock protect close"},
{"encryptionstatus", "Check if the wallet is encrypted and locked", "",
"Reports whether the wallet is encrypted and, if so, whether it is currently locked or unlocked.",
"encryptionstatus", "encryption status locked unlocked encrypted state"},
};
const ConsoleCommandEntry kLiteAdvancedCommands[] = {
{"sietch", "Create a Sietch address", "[type]",
"Creates a Sietch address, used for enhanced-privacy sends. Pass zs for a sapling Sietch address.",
"sietch zs", "sietch privacy address decoy sapling advanced"},
{"saplingtree", "Dump the latest Sapling commitment tree (debug)", "",
"Prints the latest Sapling commitment tree state \xE2\x80\x94 a debugging aid, not needed for everyday use.",
"saplingtree", "sapling tree commitment debug advanced merkle"},
{"coinsupply", "Get the coin supply info", "",
"Reports coin-supply figures for the chain as seen by the wallet's server.",
"coinsupply", "supply coins total emission circulating amount"},
};
} // namespace
const std::vector<ConsoleCommandCategory>& consoleCommandCategories()
@@ -296,5 +395,17 @@ const std::vector<ConsoleCommandCategory>& consoleCommandCategories()
return categories;
}
const std::vector<ConsoleCommandCategory>& liteConsoleCommandCategories()
{
static const std::vector<ConsoleCommandCategory> categories = {
{"Wallet", kLiteWalletCommands, CountOf(kLiteWalletCommands)},
{"Sync", kLiteSyncCommands, CountOf(kLiteSyncCommands)},
{"Send", kLiteSendCommands, CountOf(kLiteSendCommands)},
{"Keys & Security", kLiteKeyCommands, CountOf(kLiteKeyCommands)},
{"Advanced", kLiteAdvancedCommands, CountOf(kLiteAdvancedCommands)},
};
return categories;
}
} // namespace ui
} // namespace dragonx

View File

@@ -23,7 +23,12 @@ struct ConsoleCommandCategory {
int count;
};
// The full-node daemon's JSON-RPC command reference (browsed by the console's command-reference modal).
const std::vector<ConsoleCommandCategory>& consoleCommandCategories();
// The lite backend's own command set (the ~25 verbs the SDXL backend accepts) — the lite-variant
// analog of the RPC reference, shown by the same modal when the executor is the lite one.
const std::vector<ConsoleCommandCategory>& liteConsoleCommandCategories();
} // namespace ui
} // namespace dragonx

View File

@@ -464,12 +464,18 @@ void ConsoleTab::render(ConsoleCommandExecutor& exec)
ImGui::EndChild();
}
void ConsoleTab::renderCommandsPopupModal()
void ConsoleTab::renderCommandsPopupModal(ConsoleCommandExecutor* exec)
{
if (!show_commands_popup_) {
return;
}
renderCommandsPopup();
// Need a backend that offers a reference table. If the console hasn't built its executor yet
// (popup can't have been opened normally) or the backend has none, just dismiss.
if (!exec || !exec->commandReference()) {
show_commands_popup_ = false;
return;
}
renderCommandsPopup(*exec);
}
void ConsoleTab::renderToolbar(ConsoleCommandExecutor& exec)
@@ -544,14 +550,16 @@ void ConsoleTab::renderToolbar(ConsoleCommandExecutor& exec)
ImGui::SameLine();
// Commands reference button (full-node RPC reference only)
if (exec.hasRpcReference()) {
// Commands reference button — shown whenever the backend offers a reference table (full-node
// JSON-RPC commands, or the lite backend's own verbs).
if (exec.commandReference()) {
if (TactileButton(TR("console_commands"), ImVec2(0, 0), schema::UI().resolveFont("button"))) {
command_search_[0] = '\0'; // fresh search each open (dismiss paths don't all reset it)
show_commands_popup_ = true;
}
if (ImGui::IsItemHovered()) {
material::Tooltip("%s", TR("console_show_rpc_ref"));
material::Tooltip("%s", exec.hasRpcReference() ? TR("console_show_rpc_ref")
: TR("console_show_backend_ref"));
}
ImGui::SameLine();
}
@@ -1561,6 +1569,11 @@ const char* consoleCategoryLabel(const char* name)
if (!std::strcmp(name, "Wallet")) return TR("console_cat_wallet");
if (!std::strcmp(name, "Raw Transactions")) return TR("console_cat_raw_transactions");
if (!std::strcmp(name, "Utility")) return TR("console_cat_utility");
// Lite backend reference categories.
if (!std::strcmp(name, "Sync")) return TR("console_cat_sync");
if (!std::strcmp(name, "Send")) return TR("console_cat_send");
if (!std::strcmp(name, "Keys & Security")) return TR("console_cat_keys");
if (!std::strcmp(name, "Advanced")) return TR("console_cat_advanced");
return name;
}
} // namespace
@@ -1580,7 +1593,7 @@ void ConsoleTab::insertCommandToInput(const ConsoleCommandEntry& cmd)
show_commands_popup_ = false;
}
void ConsoleTab::renderCommandDetail(const ConsoleCommandEntry& cmd, const char* catLabel)
void ConsoleTab::renderCommandDetail(const ConsoleCommandEntry& cmd, const char* catLabel, bool jsonArgs)
{
using namespace material;
float dp = Layout::dpiScale();
@@ -1631,8 +1644,11 @@ void ConsoleTab::renderCommandDetail(const ConsoleCommandEntry& cmd, const char*
ImGui::PopFont();
ImGui::SameLine(labelW);
ImGui::SetNextItemWidth(-1);
// Lite backend args are bare freeform tokens, so its param types (string/number) don't
// apply — show a neutral "value" hint there instead of a misleading "number".
std::string typeHint = jsonArgs ? s.type : std::string(TR("console_ref_value"));
std::string hint = s.optional
? (s.type + " \xC2\xB7 " + std::string(TR("console_ref_optional"))) : s.type;
? (typeHint + " \xC2\xB7 " + std::string(TR("console_ref_optional"))) : typeHint;
ImGui::InputTextWithHint("##pv", hint.c_str(), cmd_param_bufs_[k], sizeof(cmd_param_bufs_[k]));
ImGui::PopID();
}
@@ -1662,7 +1678,9 @@ void ConsoleTab::renderCommandDetail(const ConsoleCommandEntry& cmd, const char*
built += " " + specs[k].raw;
complete = false;
} else {
if (specs[k].type == "string" && val.front() != '"' && val.front() != '\'' &&
// JSON-RPC (full node) auto-quotes string args; the lite backend takes bare tokens, so
// leave the value exactly as typed there (quoting would break its address/key parsing).
if (jsonArgs && specs[k].type == "string" && val.front() != '"' && val.front() != '\'' &&
val.front() != '[' && val.front() != '{')
val = "\"" + val + "\"";
built += " " + val;
@@ -1735,13 +1753,16 @@ void ConsoleTab::renderCommandDetail(const ConsoleCommandEntry& cmd, const char*
}
}
void ConsoleTab::renderCommandsPopup()
void ConsoleTab::renderCommandsPopup(ConsoleCommandExecutor& exec)
{
using namespace material;
float dp = Layout::dpiScale();
// Full node speaks JSON-RPC (quote string args); the lite backend takes bare tokens.
const bool jsonArgs = exec.hasRpcReference();
material::OverlayDialogSpec ov;
ov.title = TR("console_rpc_reference");
ov.title = jsonArgs ? TR("console_rpc_reference") : TR("console_backend_reference");
ov.p_open = &show_commands_popup_;
ov.style = material::OverlayStyle::BlurFloat; // floating content on the blur, plain heading
ov.cardWidth = 960.0f; // wide enough for two panes
@@ -1770,7 +1791,7 @@ void ConsoleTab::renderCommandsPopup()
std::transform(q.begin(), q.end(), q.begin(), ::tolower);
const bool searching = !q.empty();
const auto& categories = consoleCommandCategories();
const auto& categories = *exec.commandReference(); // non-null: guarded by renderCommandsPopupModal
// Flat display order of (cat,idx): ranked when searching, category order when browsing. Drives
// keyboard nav + auto-selection; the browse view still renders grouped headers below.
@@ -1912,7 +1933,7 @@ void ConsoleTab::renderCommandsPopup()
if (cmd_sel_cat_ >= 0 && cmd_sel_cat_ < (int)categories.size() &&
cmd_sel_idx_ >= 0 && cmd_sel_idx_ < categories[cmd_sel_cat_].count) {
renderCommandDetail(categories[cmd_sel_cat_].commands[cmd_sel_idx_],
consoleCategoryLabel(categories[cmd_sel_cat_].name));
consoleCategoryLabel(categories[cmd_sel_cat_].name), jsonArgs);
} else {
ImVec2 av = ImGui::GetContentRegionAvail();
ImGui::SetCursorPosY(av.y * 0.4f);

View File

@@ -44,10 +44,11 @@ public:
void render(ConsoleCommandExecutor& exec);
/**
* @brief Render the RPC Command Reference popup at top-level scope.
* Must be called outside any child window so the modal blocks all input.
* @brief Render the command-reference popup at top-level scope.
* Must be called outside any child window so the modal blocks all input. `exec` supplies the
* reference table (full-node RPC vs lite backend verbs); may be null (no console yet) -> no-op.
*/
void renderCommandsPopupModal();
void renderCommandsPopupModal(ConsoleCommandExecutor* exec);
// Debug/UI-sweep hook: force the RPC command-reference popup open/closed so the full UI sweep
// can capture it (the popup is otherwise opened only by a toolbar button).
@@ -115,8 +116,9 @@ private:
// Format a completed command result (JSON role -> channel) into console lines.
void addFormattedResult(const std::string& result, bool is_error);
void renderStatusHeader(ConsoleCommandExecutor& exec);
void renderCommandsPopup();
void renderCommandDetail(const ConsoleCommandEntry& cmd, const char* catLabel); // right pane
void renderCommandsPopup(ConsoleCommandExecutor& exec);
// right pane; jsonArgs=true (full-node RPC) auto-quotes string args, false (lite) inserts bare
void renderCommandDetail(const ConsoleCommandEntry& cmd, const char* catLabel, bool jsonArgs);
void insertCommandToInput(const ConsoleCommandEntry& cmd); // fill input + close the modal
// renderToolbar() draws the top bar; these are its sub-steps:
@@ -186,10 +188,11 @@ private:
// consumed by the renderer + hit-testing.
mutable ConsoleLayout layout_;
// Commands popup (RPC command explorer)
// Commands popup (command explorer) — indexes into the active executor's commandReference()
// table (full-node RPC commands or the lite backend verbs), not always the full-node one.
bool show_commands_popup_ = false;
char command_search_[128] = {0}; // RPC-reference search filter (cleared when the modal opens)
int cmd_sel_cat_ = -1; // detail-pane selection: category index into consoleCommandCategories()
char command_search_[128] = {0}; // reference search filter (cleared when the modal opens)
int cmd_sel_cat_ = -1; // detail-pane selection: category index into that table
int cmd_sel_idx_ = -1; // detail-pane selection: command index within that category
std::string pending_submit_; // command to run next frame (deferred so the modal needs no executor)
const ConsoleCommandEntry* run_confirm_cmd_ = nullptr; // destructive "Insert & run" awaiting confirmation

View File

@@ -1440,6 +1440,7 @@ void I18n::loadBuiltinEnglish()
strings_["console_no_daemon"] = "No daemon";
strings_["console_not_connected"] = "Error: Not connected to daemon";
strings_["console_rpc_reference"] = "RPC Command Reference";
strings_["console_backend_reference"] = "Backend Command Reference";
strings_["console_rpc_trace"] = "RPC";
strings_["console_app"] = "App";
strings_["console_show_app_output"] = "Show [app] wallet log lines";
@@ -1448,6 +1449,7 @@ void I18n::loadBuiltinEnglish()
strings_["console_show_daemon_output"] = "Show daemon output";
strings_["console_show_errors_only"] = "Show errors only";
strings_["console_show_rpc_ref"] = "Show RPC command reference";
strings_["console_show_backend_ref"] = "Show backend command reference";
strings_["console_show_rpc_trace"] = "Show app RPC calls";
strings_["console_showing_lines"] = "Showing %zu of %zu lines";
strings_["console_starting_node"] = "Starting node...";
@@ -1473,10 +1475,15 @@ void I18n::loadBuiltinEnglish()
strings_["console_cat_wallet"] = "Wallet";
strings_["console_cat_raw_transactions"] = "Raw Transactions";
strings_["console_cat_utility"] = "Utility";
strings_["console_cat_sync"] = "Sync";
strings_["console_cat_send"] = "Send";
strings_["console_cat_keys"] = "Keys & Security";
strings_["console_cat_advanced"] = "Advanced";
strings_["console_ref_search_hint"] = "Search by name or task\xE2\x80\xA6";
strings_["console_ref_parameters"] = "Parameters";
strings_["console_ref_no_params"] = "Takes no parameters.";
strings_["console_ref_optional"] = "optional";
strings_["console_ref_value"] = "value";
strings_["console_ref_example"] = "Example";
strings_["console_ref_builds"] = "Builds";
strings_["console_ref_destructive"] = "Consequential";