routstrd 0.4.11 → 0.4.12
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.
- package/README.md +22 -1
- package/SKILL.md +29 -4
- package/dist/daemon/index.js +93713 -72282
- package/dist/index.js +65080 -43216
- package/package.json +2 -2
- package/src/cli.ts +358 -23
- package/src/daemon/http/index.ts +318 -27
- package/src/daemon/http/request-path.ts +39 -0
- package/src/daemon/index.ts +1 -1
- package/src/daemon/models.ts +46 -11
- package/src/daemon/wallet/auto-refill.ts +20 -8
- package/src/daemon/wallet/cleanup.ts +16 -2
- package/src/daemon/wallet/coco-client.ts +921 -110
- package/src/daemon/wallet/index.ts +168 -50
- package/src/daemon/wallet/mint-quote-recovery.ts +119 -0
- package/src/daemon/wallet/recovery-probe.ts +312 -0
- package/src/daemon/wallet/recovery-work.ts +45 -0
- package/src/daemon/wallet/testing/fake-mint.ts +347 -0
- package/src/daemon/wallet/trusted-mints.ts +3 -3
- package/src/daemon/wallet/wallet-client.ts +206 -0
- package/src/integrations/pi.ts +53 -3
- package/src/utils/config.ts +3 -2
- package/src/utils/cooldowns.ts +134 -0
- package/src/utils/daemon-client.ts +53 -9
- package/src/utils/history.ts +9 -0
- package/src/utils/with-timeout.ts +21 -0
- package/src/daemon/wallet/cocod-client.ts +0 -505
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
//
|
|
5
5
|
// Uses applesauce-wallet-connect (same approach as nwc_integration/pay_invoice.mts).
|
|
6
6
|
|
|
7
|
-
import type {
|
|
7
|
+
import type { WalletClient } from "./wallet-client";
|
|
8
8
|
import type { WalletConnect } from "applesauce-wallet-connect";
|
|
9
9
|
import { logger } from "../../utils/logger";
|
|
10
10
|
|
|
@@ -33,10 +33,19 @@ function isFatalError(message: string): boolean {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export function startAutoRefillLoop(
|
|
36
|
-
|
|
36
|
+
walletClient: WalletClient,
|
|
37
37
|
getWallet: () => WalletConnect | undefined,
|
|
38
38
|
getConfig: () => AutoRefillConfig | undefined,
|
|
39
39
|
intervalMs: number = 5000,
|
|
40
|
+
payInvoice: (
|
|
41
|
+
invoice: string,
|
|
42
|
+
) => Promise<{ preimage?: string; fees_paid?: number }> = (invoice) => {
|
|
43
|
+
const wallet = getWallet();
|
|
44
|
+
if (!wallet?.service) {
|
|
45
|
+
return Promise.reject(new Error("NWC not connected"));
|
|
46
|
+
}
|
|
47
|
+
return wallet.payInvoice(invoice);
|
|
48
|
+
},
|
|
40
49
|
): () => void {
|
|
41
50
|
let lastRefillAt = 0;
|
|
42
51
|
let lastAttemptAt = 0; // tracks last attempt (success or failure) for backoff
|
|
@@ -79,7 +88,7 @@ export function startAutoRefillLoop(
|
|
|
79
88
|
checkInProgress = true;
|
|
80
89
|
|
|
81
90
|
try {
|
|
82
|
-
const balances = await
|
|
91
|
+
const balances = await walletClient.getBalances();
|
|
83
92
|
const totalBalance = Object.values(balances).reduce<number>(
|
|
84
93
|
(sum, b) => sum + (typeof b === "number" ? b : 0),
|
|
85
94
|
0,
|
|
@@ -94,17 +103,20 @@ export function startAutoRefillLoop(
|
|
|
94
103
|
`[auto-refill] Balance ${totalBalance} sats < threshold ${config.threshold}. Refilling ${config.amount} sats...`,
|
|
95
104
|
);
|
|
96
105
|
|
|
97
|
-
const mintUrl = await
|
|
106
|
+
const mintUrl = await walletClient.getDefaultMint();
|
|
98
107
|
if (!mintUrl) {
|
|
99
108
|
logger.error("[auto-refill] No default mint configured");
|
|
100
109
|
return;
|
|
101
110
|
}
|
|
102
111
|
|
|
103
|
-
// Step 1: Create a BOLT-11 invoice via
|
|
112
|
+
// Step 1: Create a BOLT-11 invoice via the wallet to fund the Cashu wallet
|
|
104
113
|
logger.log(
|
|
105
114
|
`[auto-refill] Creating BOLT-11 invoice for ${config.amount} sats via ${mintUrl}...`,
|
|
106
115
|
);
|
|
107
|
-
const { invoice } = await
|
|
116
|
+
const { invoice } = await walletClient.receiveBolt11(
|
|
117
|
+
config.amount,
|
|
118
|
+
mintUrl,
|
|
119
|
+
);
|
|
108
120
|
|
|
109
121
|
// Step 2: Pay the invoice via NWC (applesauce)
|
|
110
122
|
logger.log(`[auto-refill] Paying invoice via NWC...`);
|
|
@@ -113,10 +125,10 @@ export function startAutoRefillLoop(
|
|
|
113
125
|
logger.log("[auto-refill] Wallet disconnected during refill check");
|
|
114
126
|
return;
|
|
115
127
|
}
|
|
116
|
-
const payment = await
|
|
128
|
+
const payment = await payInvoice(invoice);
|
|
117
129
|
|
|
118
130
|
// Step 3: The Cashu mint should automatically detect the paid invoice
|
|
119
|
-
// and issue tokens. We don't need to explicitly mint here;
|
|
131
|
+
// and issue tokens. We don't need to explicitly mint here; the wallet
|
|
120
132
|
// handles this on its end when the mint sees the payment.
|
|
121
133
|
const preimage = payment.preimage;
|
|
122
134
|
if (preimage) {
|
|
@@ -64,8 +64,8 @@ export interface CleanupSelection<
|
|
|
64
64
|
* can have happened before expiry while the daemon was down, leaving no
|
|
65
65
|
* local observation. Callers that fail quotes automatically at startup must
|
|
66
66
|
* therefore confirm UNPAID with the mint first (see
|
|
67
|
-
*
|
|
68
|
-
*
|
|
67
|
+
* failExpiredMintQuoteIfUnpaid in coco-client.ts). Explicit cleanup follows
|
|
68
|
+
* the same rule unless the operator opts into unsafe `--force` behaviour.
|
|
69
69
|
* - Pending sends are reclaimed (rolled back) only when they are older than
|
|
70
70
|
* `minAgeMs`, so we never roll back a token that a receiver might still
|
|
71
71
|
* legitimately claim.
|
|
@@ -102,3 +102,17 @@ export function selectCleanupOperations<
|
|
|
102
102
|
|
|
103
103
|
return { mintsToFail, sendsToReclaim, meltsToCancel };
|
|
104
104
|
}
|
|
105
|
+
|
|
106
|
+
/** Keep a local-only dry-run preview distinct from mint-confirmed outcomes. */
|
|
107
|
+
export function summarizeMintCleanup(input: {
|
|
108
|
+
dryRun: boolean;
|
|
109
|
+
candidates: number;
|
|
110
|
+
failed: number;
|
|
111
|
+
leftForRecovery: number;
|
|
112
|
+
}) {
|
|
113
|
+
return {
|
|
114
|
+
mintQuoteCandidates: input.candidates,
|
|
115
|
+
failedMintQuotes: input.dryRun ? 0 : input.failed,
|
|
116
|
+
leftForRecovery: input.dryRun ? 0 : input.leftForRecovery,
|
|
117
|
+
};
|
|
118
|
+
}
|