mirror of
https://github.com/Routstr/routstrd.git
synced 2026-08-09 03:44:38 +00:00
feat: auto-refill no longer requires daemon restart
Changed startAutoRefillLoop to accept a config getter instead of a static config object. The getter reads config from disk on every check cycle, so CLI changes (nwc auto-refill on/off) take effect immediately. - auto-refill.ts: config parameter replaced with getConfig() callback - wallet/index.ts: always start loop when wallet exists, use getter - daemon/index.ts: pass getAutoRefillConfig reading from disk sync - config-store.ts: added loadDaemonConfigSync() for sync disk reads - http/index.ts + cli.ts: removed 'Restart daemon to apply' messages
This commit is contained in:
+3
-9
@@ -1309,13 +1309,9 @@ nwcCmd
|
||||
});
|
||||
}
|
||||
|
||||
// Validate the connection string format
|
||||
const { validateConnectionString } = await import(
|
||||
"./daemon/wallet/nwc-client"
|
||||
);
|
||||
const validation = validateConnectionString(connectionString);
|
||||
if (!validation.valid) {
|
||||
console.error(`Invalid NWC connection string: ${validation.error}`);
|
||||
// Quick validation: must be nostr+walletconnect:// with a 64-char hex pubkey
|
||||
if (!/^nostr\+walletconnect:\/\/[0-9a-fA-F]{64}\?relay=/.test(connectionString)) {
|
||||
console.error("Invalid NWC connection string: expected nostr+walletconnect://<64-char-hex>?relay=...");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@@ -1387,7 +1383,6 @@ autoRefillCmd
|
||||
cooldownMs: cooldownSec * 1000,
|
||||
},
|
||||
});
|
||||
console.log("\nRun 'routstrd restart' to apply.");
|
||||
});
|
||||
|
||||
autoRefillCmd
|
||||
@@ -1398,7 +1393,6 @@ autoRefillCmd
|
||||
method: "POST",
|
||||
body: { enabled: false },
|
||||
});
|
||||
console.log("\nRun 'routstrd restart' to apply.");
|
||||
});
|
||||
|
||||
// Stop
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { mkdir } from "fs/promises";
|
||||
import { existsSync } from "fs";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import {
|
||||
CONFIG_DIR,
|
||||
CONFIG_FILE,
|
||||
@@ -31,6 +31,18 @@ export async function loadDaemonConfig(): Promise<RoutstrdConfig> {
|
||||
return DEFAULT_CONFIG;
|
||||
}
|
||||
|
||||
export function loadDaemonConfigSync(): RoutstrdConfig {
|
||||
try {
|
||||
if (existsSync(CONFIG_FILE)) {
|
||||
const content = readFileSync(CONFIG_FILE, "utf-8");
|
||||
return { ...DEFAULT_CONFIG, ...JSON.parse(content) };
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error("Failed to load config:", error);
|
||||
}
|
||||
return DEFAULT_CONFIG;
|
||||
}
|
||||
|
||||
export function saveDaemonConfig(config: RoutstrdConfig): void {
|
||||
Bun.write(CONFIG_FILE, JSON.stringify(config, null, 2));
|
||||
}
|
||||
|
||||
@@ -558,7 +558,7 @@ export function createDaemonRequestHandler(deps: {
|
||||
|
||||
return {
|
||||
output: {
|
||||
message: `Auto-refill ${enabled ? "enabled" : "disabled"}. Restart daemon to apply.`,
|
||||
message: `Auto-refill ${enabled ? "enabled" : "disabled"}.`,
|
||||
autoRefill: config.nwc.autoRefill,
|
||||
},
|
||||
};
|
||||
|
||||
+16
-10
@@ -26,12 +26,13 @@ function makeSdkLogger(prefix?: string): SdkLogger {
|
||||
}
|
||||
const daemonSdkLogger: SdkLogger = makeSdkLogger();
|
||||
import { parseArgs } from "./args";
|
||||
import { ensureDirs, loadDaemonConfig, saveDaemonConfig } from "./config-store";
|
||||
import { ensureDirs, loadDaemonConfig, loadDaemonConfigSync, saveDaemonConfig } from "./config-store";
|
||||
import {
|
||||
createBunSqliteDriver,
|
||||
createBunSqliteUsageTrackingDriver,
|
||||
} from "@routstr/sdk/storage";
|
||||
import { createWalletAdapter } from "./wallet";
|
||||
import type { AutoRefillConfig } from "./wallet/auto-refill";
|
||||
import { createCocodClient } from "./wallet/cocod-client";
|
||||
import { createModelService } from "./models";
|
||||
import { createDaemonRequestHandler } from "./http";
|
||||
@@ -72,20 +73,25 @@ async function main(): Promise<void> {
|
||||
const walletClient = createCocodClient({ cocodPath: config.cocodPath });
|
||||
|
||||
// ── Auto-refill configuration ────────────────────────────────
|
||||
// Uses a getter that reads config from disk each cycle, so
|
||||
// CLI changes take effect immediately without a daemon restart.
|
||||
|
||||
const nwcAutoRefill =
|
||||
config.nwc?.autoRefill?.enabled && config.nwc?.connectionString
|
||||
? {
|
||||
threshold: config.nwc.autoRefill.threshold,
|
||||
amount: config.nwc.autoRefill.amount,
|
||||
cooldownMs: config.nwc.autoRefill.cooldownMs,
|
||||
}
|
||||
: undefined;
|
||||
const getAutoRefillConfig = (): AutoRefillConfig | undefined => {
|
||||
const cfg = loadDaemonConfigSync();
|
||||
if (cfg.nwc?.autoRefill?.enabled && cfg.nwc?.connectionString) {
|
||||
return {
|
||||
threshold: cfg.nwc.autoRefill.threshold,
|
||||
amount: cfg.nwc.autoRefill.amount,
|
||||
cooldownMs: cfg.nwc.autoRefill.cooldownMs,
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const walletAdapter = await createWalletAdapter({
|
||||
cocodPath: config.cocodPath,
|
||||
walletClient,
|
||||
autoRefill: nwcAutoRefill,
|
||||
getAutoRefillConfig,
|
||||
nwcConnectionString: config.nwc?.connectionString,
|
||||
});
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ export interface AutoRefillConfig {
|
||||
export function startAutoRefillLoop(
|
||||
cocod: CocodClient,
|
||||
wallet: WalletConnect,
|
||||
config: AutoRefillConfig,
|
||||
getConfig: () => AutoRefillConfig | undefined,
|
||||
intervalMs: number = 5000,
|
||||
): () => void {
|
||||
let lastRefillAt = 0;
|
||||
@@ -36,6 +36,13 @@ export function startAutoRefillLoop(
|
||||
return;
|
||||
}
|
||||
|
||||
// Read config fresh each cycle so changes apply without restart
|
||||
const config = getConfig();
|
||||
if (!config) {
|
||||
// Auto-refill disabled
|
||||
return;
|
||||
}
|
||||
|
||||
const now = Date.now();
|
||||
if (now - lastRefillAt < config.cooldownMs) {
|
||||
return;
|
||||
|
||||
@@ -22,8 +22,14 @@ export interface WalletAdapterOptions {
|
||||
walletClient?: CocodClient;
|
||||
/** NWC connection string for Lightning funding (uses applesauce-wallet-connect) */
|
||||
nwcConnectionString?: string;
|
||||
/** Auto-refill configuration */
|
||||
/** Auto-refill configuration (static, for startup only) */
|
||||
autoRefill?: AutoRefillConfig;
|
||||
/**
|
||||
* Config getter called on every check cycle to allow live updates.
|
||||
* Return undefined to disable auto-refill, or a config to use.
|
||||
* When provided, this replaces the static `autoRefill` option.
|
||||
*/
|
||||
getAutoRefillConfig?: () => AutoRefillConfig | undefined;
|
||||
}
|
||||
|
||||
export async function createWalletAdapter(
|
||||
@@ -266,15 +272,21 @@ export async function createWalletAdapter(
|
||||
|
||||
let stopAutoRefill: (() => void) | undefined;
|
||||
|
||||
if (options.autoRefill && wallet) {
|
||||
stopAutoRefill = startAutoRefillLoop(
|
||||
client,
|
||||
wallet,
|
||||
options.autoRefill,
|
||||
);
|
||||
const autoRefillConfig = options.getAutoRefillConfig
|
||||
? options.getAutoRefillConfig()
|
||||
: options.autoRefill;
|
||||
|
||||
if (autoRefillConfig && wallet) {
|
||||
const getConfig = options.getAutoRefillConfig ?? (() => options.autoRefill);
|
||||
stopAutoRefill = startAutoRefillLoop(client, wallet, getConfig);
|
||||
logger.log(
|
||||
`[wallet] Auto-refill enabled: threshold=${options.autoRefill.threshold} sats, amount=${options.autoRefill.amount} sats, cooldown=${options.autoRefill.cooldownMs}ms`,
|
||||
`[wallet] Auto-refill enabled: threshold=${autoRefillConfig.threshold} sats, amount=${autoRefillConfig.amount} sats, cooldown=${autoRefillConfig.cooldownMs}ms`,
|
||||
);
|
||||
} else if (wallet && options.getAutoRefillConfig) {
|
||||
// Wallet exists but auto-refill is not currently enabled.
|
||||
// Start the loop anyway so it can pick up changes without a restart.
|
||||
stopAutoRefill = startAutoRefillLoop(client, wallet, options.getAutoRefillConfig);
|
||||
logger.log("[wallet] Auto-refill loop started (currently disabled — enable via CLI to activate)");
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user