mirror of
https://github.com/Routstr/routstrd.git
synced 2026-10-05 12:28:23 +00:00
fix(cli): warn when wallet is recovering during send/receive
Value-moving wallet operations block on the daemon's recovery gate until startup recovery completes, so send/receive appeared to hang silently after a restart. Print a clear 'wallet is recovering, please wait' notice (and the current recovery phase) before these commands, sourced from /wallet/status. Reads stay unaffected and the status probe is best-effort.
This commit is contained in:
+36
@@ -155,6 +155,36 @@ async function waitForMintQuote(operationId: string): Promise<void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warn that value-moving wallet operations will block until startup recovery
|
||||||
|
* finishes. Reads stay available, but the daemon gates send/receive behind the
|
||||||
|
* recovery gate, so without this notice the CLI would appear to hang silently
|
||||||
|
* after a restart.
|
||||||
|
*/
|
||||||
|
async function warnIfWalletRecovering(): Promise<void> {
|
||||||
|
try {
|
||||||
|
await ensureDaemonRunning();
|
||||||
|
const result = await callDaemon("/wallet/status");
|
||||||
|
const output = result.output as
|
||||||
|
| { state?: string; recovery?: { phase?: string } }
|
||||||
|
| undefined;
|
||||||
|
if (output?.state !== "RECOVERING") return;
|
||||||
|
|
||||||
|
const phase = output.recovery?.phase;
|
||||||
|
console.error(
|
||||||
|
"Wallet is recovering from a previous run (this only happens after a restart).",
|
||||||
|
);
|
||||||
|
if (phase && phase !== "done") {
|
||||||
|
console.error(`Recovery phase: ${phase}.`);
|
||||||
|
}
|
||||||
|
console.error(
|
||||||
|
"Please wait — send and receive resume as soon as recovery completes.",
|
||||||
|
);
|
||||||
|
} catch {
|
||||||
|
// Status is best-effort; never block the real command on it.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function initializeWallet(walletDir = defaultWalletDir()): void {
|
export function initializeWallet(walletDir = defaultWalletDir()): void {
|
||||||
const walletConfig = join(walletDir, "config.json");
|
const walletConfig = join(walletDir, "config.json");
|
||||||
|
|
||||||
@@ -1950,6 +1980,7 @@ program
|
|||||||
)
|
)
|
||||||
.option("--mint-url <url>", "Mint URL to use")
|
.option("--mint-url <url>", "Mint URL to use")
|
||||||
.action(async (target: string, options: { mintUrl?: string }) => {
|
.action(async (target: string, options: { mintUrl?: string }) => {
|
||||||
|
await warnIfWalletRecovering();
|
||||||
if (isPositiveIntegerString(target)) {
|
if (isPositiveIntegerString(target)) {
|
||||||
await handleDaemonCommand("/wallet/send/cashu", {
|
await handleDaemonCommand("/wallet/send/cashu", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@@ -1977,6 +2008,7 @@ program
|
|||||||
)
|
)
|
||||||
.option("--mint-url <url>", "Mint URL to use for bolt11 receive")
|
.option("--mint-url <url>", "Mint URL to use for bolt11 receive")
|
||||||
.action(async (value: string, options: { mintUrl?: string }) => {
|
.action(async (value: string, options: { mintUrl?: string }) => {
|
||||||
|
await warnIfWalletRecovering();
|
||||||
if (isPositiveIntegerString(value)) {
|
if (isPositiveIntegerString(value)) {
|
||||||
try {
|
try {
|
||||||
await ensureDaemonRunning();
|
await ensureDaemonRunning();
|
||||||
@@ -2304,6 +2336,7 @@ walletReceiveCmd
|
|||||||
.command("cashu <token>")
|
.command("cashu <token>")
|
||||||
.description("Receive a Cashu token")
|
.description("Receive a Cashu token")
|
||||||
.action(async (token: string) => {
|
.action(async (token: string) => {
|
||||||
|
await warnIfWalletRecovering();
|
||||||
await handleDaemonCommand("/wallet/receive/cashu", {
|
await handleDaemonCommand("/wallet/receive/cashu", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: { token },
|
body: { token },
|
||||||
@@ -2315,6 +2348,7 @@ walletReceiveCmd
|
|||||||
.description("Create a Lightning invoice")
|
.description("Create a Lightning invoice")
|
||||||
.option("--mint-url <url>", "Mint URL to use")
|
.option("--mint-url <url>", "Mint URL to use")
|
||||||
.action(async (amount: string, options: { mintUrl?: string }) => {
|
.action(async (amount: string, options: { mintUrl?: string }) => {
|
||||||
|
await warnIfWalletRecovering();
|
||||||
try {
|
try {
|
||||||
await ensureDaemonRunning();
|
await ensureDaemonRunning();
|
||||||
|
|
||||||
@@ -2353,6 +2387,7 @@ walletSendCmd
|
|||||||
.description("Create a Cashu token to send")
|
.description("Create a Cashu token to send")
|
||||||
.option("--mint-url <url>", "Mint URL to use")
|
.option("--mint-url <url>", "Mint URL to use")
|
||||||
.action(async (amount: string, options: { mintUrl?: string }) => {
|
.action(async (amount: string, options: { mintUrl?: string }) => {
|
||||||
|
await warnIfWalletRecovering();
|
||||||
await handleDaemonCommand("/wallet/send/cashu", {
|
await handleDaemonCommand("/wallet/send/cashu", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: {
|
body: {
|
||||||
@@ -2367,6 +2402,7 @@ walletSendCmd
|
|||||||
.description("Pay a Lightning invoice")
|
.description("Pay a Lightning invoice")
|
||||||
.option("--mint-url <url>", "Mint URL to use")
|
.option("--mint-url <url>", "Mint URL to use")
|
||||||
.action(async (invoice: string, options: { mintUrl?: string }) => {
|
.action(async (invoice: string, options: { mintUrl?: string }) => {
|
||||||
|
await warnIfWalletRecovering();
|
||||||
await handleDaemonCommand("/wallet/send/bolt11", {
|
await handleDaemonCommand("/wallet/send/bolt11", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: {
|
body: {
|
||||||
|
|||||||
Reference in New Issue
Block a user