routstrd 0.2.22 → 0.3.1
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/.claude/settings.local.json +10 -0
- package/Dockerfile +8 -0
- package/bun.lock +165 -9
- package/dist/daemon/index.js +42891 -20990
- package/dist/index.js +417 -169
- package/docker-compose.yml +8 -7
- package/new-task.md +60 -0
- package/package.json +3 -2
- package/src/cli.ts +178 -22
- package/src/daemon/config-store.ts +13 -1
- package/src/daemon/wallet/auto-refill.ts +192 -0
- package/src/integrations/claudecode.ts +9 -10
- package/src/integrations/hermes.ts +10 -11
- package/src/integrations/openclaw.ts +5 -6
- package/src/integrations/opencode.ts +5 -6
- package/src/integrations/pi.ts +13 -9
- package/src/integrations/registry.ts +1 -0
- package/src/utils/clients.ts +4 -3
- package/src/utils/config.ts +27 -0
- package/src/utils/daemon-client.ts +32 -5
package/dist/index.js
CHANGED
|
@@ -27,6 +27,7 @@ var __export = (target, all) => {
|
|
|
27
27
|
});
|
|
28
28
|
};
|
|
29
29
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
30
|
+
var __require = import.meta.require;
|
|
30
31
|
|
|
31
32
|
// node_modules/commander/lib/error.js
|
|
32
33
|
var require_error = __commonJS((exports) => {
|
|
@@ -748,11 +749,11 @@ var require_suggestSimilar = __commonJS((exports) => {
|
|
|
748
749
|
|
|
749
750
|
// node_modules/commander/lib/command.js
|
|
750
751
|
var require_command = __commonJS((exports) => {
|
|
751
|
-
var EventEmitter =
|
|
752
|
-
var childProcess =
|
|
753
|
-
var path =
|
|
754
|
-
var fs =
|
|
755
|
-
var process2 =
|
|
752
|
+
var EventEmitter = __require("events").EventEmitter;
|
|
753
|
+
var childProcess = __require("child_process");
|
|
754
|
+
var path = __require("path");
|
|
755
|
+
var fs = __require("fs");
|
|
756
|
+
var process2 = __require("process");
|
|
756
757
|
var { Argument, humanReadableArgName } = require_argument();
|
|
757
758
|
var { CommanderError } = require_error();
|
|
758
759
|
var { Help, stripColor } = require_help();
|
|
@@ -1000,8 +1001,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1000
1001
|
this._exitCallback = (err) => {
|
|
1001
1002
|
if (err.code !== "commander.executeSubCommandAsync") {
|
|
1002
1003
|
throw err;
|
|
1003
|
-
} else {
|
|
1004
|
-
}
|
|
1004
|
+
} else {}
|
|
1005
1005
|
};
|
|
1006
1006
|
}
|
|
1007
1007
|
return this;
|
|
@@ -2235,8 +2235,7 @@ async function readLockOwner(lockDir) {
|
|
|
2235
2235
|
token: typeof parsed.token === "string" ? parsed.token : undefined
|
|
2236
2236
|
};
|
|
2237
2237
|
}
|
|
2238
|
-
} catch {
|
|
2239
|
-
}
|
|
2238
|
+
} catch {}
|
|
2240
2239
|
return null;
|
|
2241
2240
|
}
|
|
2242
2241
|
async function isLockStale(lockDir, staleAfterMs) {
|
|
@@ -2298,8 +2297,7 @@ async function withCrossProcessLock(lockDir, fn, options = {}) {
|
|
|
2298
2297
|
await release();
|
|
2299
2298
|
}
|
|
2300
2299
|
}
|
|
2301
|
-
var init_process_lock = () => {
|
|
2302
|
-
};
|
|
2300
|
+
var init_process_lock = () => {};
|
|
2303
2301
|
|
|
2304
2302
|
// src/start-daemon.ts
|
|
2305
2303
|
async function isDaemonHealthy(port) {
|
|
@@ -5220,8 +5218,7 @@ function unsafeWrapper(fn) {
|
|
|
5220
5218
|
return function(...args) {
|
|
5221
5219
|
try {
|
|
5222
5220
|
return fn.apply(null, args);
|
|
5223
|
-
} catch (e) {
|
|
5224
|
-
}
|
|
5221
|
+
} catch (e) {}
|
|
5225
5222
|
};
|
|
5226
5223
|
}
|
|
5227
5224
|
function bech32Polymod(pre) {
|
|
@@ -7171,28 +7168,49 @@ function calcPaddedLen(len) {
|
|
|
7171
7168
|
throw new Error("expected positive integer");
|
|
7172
7169
|
if (len <= 32)
|
|
7173
7170
|
return 32;
|
|
7174
|
-
const nextPower =
|
|
7171
|
+
const nextPower = 2 ** (Math.floor(Math.log2(len - 1)) + 1);
|
|
7175
7172
|
const chunk = nextPower <= 256 ? 32 : nextPower / 8;
|
|
7176
7173
|
return chunk * (Math.floor((len - 1) / chunk) + 1);
|
|
7177
7174
|
}
|
|
7178
7175
|
function writeU16BE(num2) {
|
|
7179
|
-
if (!Number.isSafeInteger(num2) || num2 < minPlaintextSize || num2 >
|
|
7176
|
+
if (!Number.isSafeInteger(num2) || num2 < minPlaintextSize || num2 > 65535)
|
|
7180
7177
|
throw new Error("invalid plaintext size: must be between 1 and 65535 bytes");
|
|
7181
7178
|
const arr = new Uint8Array(2);
|
|
7182
7179
|
new DataView(arr.buffer).setUint16(0, num2, false);
|
|
7183
7180
|
return arr;
|
|
7184
7181
|
}
|
|
7182
|
+
function writeU32BE(num2) {
|
|
7183
|
+
if (!Number.isSafeInteger(num2) || num2 < extendedPrefixThreshold || num2 > maxPlaintextSize)
|
|
7184
|
+
throw new Error("invalid plaintext size: must be between 65536 and 4294967295 bytes");
|
|
7185
|
+
const arr = new Uint8Array(4);
|
|
7186
|
+
new DataView(arr.buffer).setUint32(0, num2, false);
|
|
7187
|
+
return arr;
|
|
7188
|
+
}
|
|
7185
7189
|
function pad(plaintext) {
|
|
7186
7190
|
const unpadded = utf8Encoder.encode(plaintext);
|
|
7187
7191
|
const unpaddedLen = unpadded.length;
|
|
7188
|
-
|
|
7192
|
+
if (unpaddedLen < minPlaintextSize || unpaddedLen > maxPlaintextSize)
|
|
7193
|
+
throw new Error("invalid plaintext size: must be between 1 and 4294967295 bytes");
|
|
7194
|
+
const prefix = unpaddedLen >= extendedPrefixThreshold ? concatBytes(new Uint8Array([0, 0]), writeU32BE(unpaddedLen)) : writeU16BE(unpaddedLen);
|
|
7189
7195
|
const suffix = new Uint8Array(calcPaddedLen(unpaddedLen) - unpaddedLen);
|
|
7190
7196
|
return concatBytes(prefix, unpadded, suffix);
|
|
7191
7197
|
}
|
|
7192
7198
|
function unpad(padded) {
|
|
7193
|
-
const
|
|
7194
|
-
const
|
|
7195
|
-
|
|
7199
|
+
const dv = new DataView(padded.buffer, padded.byteOffset, padded.byteLength);
|
|
7200
|
+
const firstTwo = dv.getUint16(0);
|
|
7201
|
+
let unpaddedLen;
|
|
7202
|
+
let prefixLen;
|
|
7203
|
+
if (firstTwo === 0) {
|
|
7204
|
+
unpaddedLen = dv.getUint32(2);
|
|
7205
|
+
if (unpaddedLen < extendedPrefixThreshold)
|
|
7206
|
+
throw new Error("invalid padding");
|
|
7207
|
+
prefixLen = 6;
|
|
7208
|
+
} else {
|
|
7209
|
+
unpaddedLen = firstTwo;
|
|
7210
|
+
prefixLen = 2;
|
|
7211
|
+
}
|
|
7212
|
+
const unpadded = padded.subarray(prefixLen, prefixLen + unpaddedLen);
|
|
7213
|
+
if (unpaddedLen < minPlaintextSize || unpaddedLen > maxPlaintextSize || unpadded.length !== unpaddedLen || padded.length !== prefixLen + calcPaddedLen(unpaddedLen))
|
|
7196
7214
|
throw new Error("invalid padding");
|
|
7197
7215
|
return utf8Decoder.decode(unpadded);
|
|
7198
7216
|
}
|
|
@@ -7206,7 +7224,7 @@ function decodePayload(payload) {
|
|
|
7206
7224
|
if (typeof payload !== "string")
|
|
7207
7225
|
throw new Error("payload must be a valid string");
|
|
7208
7226
|
const plen = payload.length;
|
|
7209
|
-
if (plen < 132
|
|
7227
|
+
if (plen < 132)
|
|
7210
7228
|
throw new Error("invalid payload length: " + plen);
|
|
7211
7229
|
if (payload[0] === "#")
|
|
7212
7230
|
throw new Error("unknown encryption version");
|
|
@@ -7217,7 +7235,7 @@ function decodePayload(payload) {
|
|
|
7217
7235
|
throw new Error("invalid base64: " + error.message);
|
|
7218
7236
|
}
|
|
7219
7237
|
const dlen = data.length;
|
|
7220
|
-
if (dlen < 99
|
|
7238
|
+
if (dlen < 99)
|
|
7221
7239
|
throw new Error("invalid data length: " + dlen);
|
|
7222
7240
|
const vers = data[0];
|
|
7223
7241
|
if (vers !== 2)
|
|
@@ -7403,6 +7421,135 @@ function parse2(uri) {
|
|
|
7403
7421
|
decoded: decode(match[1])
|
|
7404
7422
|
};
|
|
7405
7423
|
}
|
|
7424
|
+
function parseKind(kind) {
|
|
7425
|
+
if (!kind)
|
|
7426
|
+
return;
|
|
7427
|
+
return /^\d+$/.test(kind) ? parseInt(kind, 10) : kind;
|
|
7428
|
+
}
|
|
7429
|
+
function parseAddressPointer(value, relayUrl) {
|
|
7430
|
+
const idx = value.indexOf(":");
|
|
7431
|
+
const idx2 = value.indexOf(":", idx + 1);
|
|
7432
|
+
if (idx === -1 || idx2 === -1)
|
|
7433
|
+
return;
|
|
7434
|
+
const kind = parseInt(value.slice(0, idx), 10);
|
|
7435
|
+
if (Number.isNaN(kind))
|
|
7436
|
+
return;
|
|
7437
|
+
return {
|
|
7438
|
+
kind,
|
|
7439
|
+
pubkey: value.slice(idx + 1, idx2),
|
|
7440
|
+
identifier: value.slice(idx2 + 1),
|
|
7441
|
+
relays: relayUrl ? [relayUrl] : []
|
|
7442
|
+
};
|
|
7443
|
+
}
|
|
7444
|
+
function parsePointer(tag) {
|
|
7445
|
+
switch (tag[0]) {
|
|
7446
|
+
case "E":
|
|
7447
|
+
case "e":
|
|
7448
|
+
if (!tag[1])
|
|
7449
|
+
return;
|
|
7450
|
+
return {
|
|
7451
|
+
id: tag[1],
|
|
7452
|
+
relays: tag[2] ? [tag[2]] : [],
|
|
7453
|
+
author: tag[3]
|
|
7454
|
+
};
|
|
7455
|
+
case "A":
|
|
7456
|
+
case "a":
|
|
7457
|
+
if (!tag[1])
|
|
7458
|
+
return;
|
|
7459
|
+
return parseAddressPointer(tag[1], tag[2]);
|
|
7460
|
+
case "I":
|
|
7461
|
+
case "i":
|
|
7462
|
+
if (!tag[1])
|
|
7463
|
+
return;
|
|
7464
|
+
return {
|
|
7465
|
+
value: tag[1],
|
|
7466
|
+
hint: tag[2]
|
|
7467
|
+
};
|
|
7468
|
+
}
|
|
7469
|
+
}
|
|
7470
|
+
function parseQuote(tag) {
|
|
7471
|
+
if (!tag[1])
|
|
7472
|
+
return;
|
|
7473
|
+
if (tag[1].includes(":")) {
|
|
7474
|
+
return parseAddressPointer(tag[1], tag[2]);
|
|
7475
|
+
}
|
|
7476
|
+
return {
|
|
7477
|
+
id: tag[1],
|
|
7478
|
+
relays: tag[2] ? [tag[2]] : [],
|
|
7479
|
+
author: tag[3]
|
|
7480
|
+
};
|
|
7481
|
+
}
|
|
7482
|
+
function choosePointer(candidates) {
|
|
7483
|
+
return candidates.findLast((candidate) => candidate.tagName === "A" || candidate.tagName === "a")?.pointer || candidates.findLast((candidate) => candidate.tagName === "I" || candidate.tagName === "i")?.pointer || candidates.findLast((candidate) => candidate.tagName === "E" || candidate.tagName === "e")?.pointer;
|
|
7484
|
+
}
|
|
7485
|
+
function inheritRelayHints(pointer, profiles) {
|
|
7486
|
+
if (!pointer || !("id" in pointer) || !pointer.author)
|
|
7487
|
+
return;
|
|
7488
|
+
const author = profiles.find((profile) => profile.pubkey === pointer.author);
|
|
7489
|
+
if (!author || !author.relays)
|
|
7490
|
+
return;
|
|
7491
|
+
if (!pointer.relays) {
|
|
7492
|
+
pointer.relays = [];
|
|
7493
|
+
}
|
|
7494
|
+
author.relays.forEach((url) => {
|
|
7495
|
+
if (pointer.relays.indexOf(url) === -1)
|
|
7496
|
+
pointer.relays.push(url);
|
|
7497
|
+
});
|
|
7498
|
+
author.relays = pointer.relays;
|
|
7499
|
+
}
|
|
7500
|
+
function parse3(event) {
|
|
7501
|
+
const result = {
|
|
7502
|
+
root: undefined,
|
|
7503
|
+
rootKind: undefined,
|
|
7504
|
+
reply: undefined,
|
|
7505
|
+
replyKind: undefined,
|
|
7506
|
+
mentions: [],
|
|
7507
|
+
quotes: [],
|
|
7508
|
+
profiles: []
|
|
7509
|
+
};
|
|
7510
|
+
const rootCandidates = [];
|
|
7511
|
+
const replyCandidates = [];
|
|
7512
|
+
for (const tag of event.tags) {
|
|
7513
|
+
if ((tag[0] === "E" || tag[0] === "A" || tag[0] === "I") && tag[1]) {
|
|
7514
|
+
const pointer = parsePointer(tag);
|
|
7515
|
+
if (pointer)
|
|
7516
|
+
rootCandidates.push({ tagName: tag[0], pointer });
|
|
7517
|
+
continue;
|
|
7518
|
+
}
|
|
7519
|
+
if ((tag[0] === "e" || tag[0] === "a" || tag[0] === "i") && tag[1]) {
|
|
7520
|
+
const pointer = parsePointer(tag);
|
|
7521
|
+
if (pointer)
|
|
7522
|
+
replyCandidates.push({ tagName: tag[0], pointer });
|
|
7523
|
+
continue;
|
|
7524
|
+
}
|
|
7525
|
+
if (tag[0] === "K") {
|
|
7526
|
+
result.rootKind = parseKind(tag[1]);
|
|
7527
|
+
continue;
|
|
7528
|
+
}
|
|
7529
|
+
if (tag[0] === "k") {
|
|
7530
|
+
result.replyKind = parseKind(tag[1]);
|
|
7531
|
+
continue;
|
|
7532
|
+
}
|
|
7533
|
+
if (tag[0] === "q") {
|
|
7534
|
+
const pointer = parseQuote(tag);
|
|
7535
|
+
if (pointer)
|
|
7536
|
+
result.quotes.push(pointer);
|
|
7537
|
+
continue;
|
|
7538
|
+
}
|
|
7539
|
+
if ((tag[0] === "P" || tag[0] === "p") && tag[1]) {
|
|
7540
|
+
result.profiles.push({
|
|
7541
|
+
pubkey: tag[1],
|
|
7542
|
+
relays: tag[2] ? [tag[2]] : []
|
|
7543
|
+
});
|
|
7544
|
+
}
|
|
7545
|
+
}
|
|
7546
|
+
result.root = choosePointer(rootCandidates);
|
|
7547
|
+
result.reply = choosePointer(replyCandidates);
|
|
7548
|
+
inheritRelayHints(result.root, result.profiles);
|
|
7549
|
+
inheritRelayHints(result.reply, result.profiles);
|
|
7550
|
+
result.quotes.forEach((pointer) => inheritRelayHints(pointer, result.profiles));
|
|
7551
|
+
return result;
|
|
7552
|
+
}
|
|
7406
7553
|
function finishReactionEvent(t, reacted, privateKey) {
|
|
7407
7554
|
const inheritedTags = reacted.tags.filter((tag) => tag.length >= 2 && (tag[0] === "e" || tag[0] === "p"));
|
|
7408
7555
|
return finalizeEvent({
|
|
@@ -7437,7 +7584,7 @@ function getReactedEventPointer(event) {
|
|
|
7437
7584
|
author: lastPTag[1]
|
|
7438
7585
|
};
|
|
7439
7586
|
}
|
|
7440
|
-
function*
|
|
7587
|
+
function* parse4(content) {
|
|
7441
7588
|
let emojis = [];
|
|
7442
7589
|
if (typeof content !== "string") {
|
|
7443
7590
|
for (let i2 = 0;i2 < content.tags.length; i2++) {
|
|
@@ -7591,8 +7738,7 @@ function* matchAll(content) {
|
|
|
7591
7738
|
start: match.index,
|
|
7592
7739
|
end: match.index + shortcode.length
|
|
7593
7740
|
};
|
|
7594
|
-
} catch (_e) {
|
|
7595
|
-
}
|
|
7741
|
+
} catch (_e) {}
|
|
7596
7742
|
}
|
|
7597
7743
|
}
|
|
7598
7744
|
function replaceAll(content, replacer) {
|
|
@@ -7617,12 +7763,12 @@ async function validateGithub(pubkey, username, proof) {
|
|
|
7617
7763
|
function parseConnectionString(connectionString) {
|
|
7618
7764
|
const { host, pathname, searchParams } = new URL(connectionString);
|
|
7619
7765
|
const pubkey = pathname || host;
|
|
7620
|
-
const
|
|
7766
|
+
const relays = searchParams.getAll("relay");
|
|
7621
7767
|
const secret = searchParams.get("secret");
|
|
7622
|
-
if (!pubkey ||
|
|
7768
|
+
if (!pubkey || relays.length === 0 || !secret) {
|
|
7623
7769
|
throw new Error("invalid connection string");
|
|
7624
7770
|
}
|
|
7625
|
-
return { pubkey, relay, secret };
|
|
7771
|
+
return { pubkey, relay: relays[0], relays, secret };
|
|
7626
7772
|
}
|
|
7627
7773
|
async function makeNwcRequestEvent(pubkey, secretKey, invoice) {
|
|
7628
7774
|
const content = {
|
|
@@ -7672,8 +7818,7 @@ async function getZapEndpoint(metadata) {
|
|
|
7672
7818
|
if (body.allowsNostr && body.nostrPubkey) {
|
|
7673
7819
|
return body.callback;
|
|
7674
7820
|
}
|
|
7675
|
-
} catch (err) {
|
|
7676
|
-
}
|
|
7821
|
+
} catch (err) {}
|
|
7677
7822
|
return null;
|
|
7678
7823
|
}
|
|
7679
7824
|
function makeZapRequest(params) {
|
|
@@ -8034,8 +8179,7 @@ var __defProp2, __export2 = (target, all) => {
|
|
|
8034
8179
|
this.reconnectTimeoutHandle = setTimeout(async () => {
|
|
8035
8180
|
try {
|
|
8036
8181
|
await this.connect();
|
|
8037
|
-
} catch (err) {
|
|
8038
|
-
}
|
|
8182
|
+
} catch (err) {}
|
|
8039
8183
|
}, backoff);
|
|
8040
8184
|
}
|
|
8041
8185
|
handleHardClose(reason) {
|
|
@@ -8339,7 +8483,11 @@ var __defProp2, __export2 = (target, all) => {
|
|
|
8339
8483
|
case "AUTH": {
|
|
8340
8484
|
this.challenge = data[1];
|
|
8341
8485
|
if (this.onauth) {
|
|
8342
|
-
this.auth(this.onauth)
|
|
8486
|
+
this.auth(this.onauth).catch((err) => {
|
|
8487
|
+
if (!(err instanceof SendingOnClosedConnection)) {
|
|
8488
|
+
throw err;
|
|
8489
|
+
}
|
|
8490
|
+
});
|
|
8343
8491
|
}
|
|
8344
8492
|
return;
|
|
8345
8493
|
}
|
|
@@ -8407,8 +8555,7 @@ var __defProp2, __export2 = (target, all) => {
|
|
|
8407
8555
|
try {
|
|
8408
8556
|
this.relay.send('["CLOSE",' + JSON.stringify(this.id) + "]");
|
|
8409
8557
|
} catch (err) {
|
|
8410
|
-
if (err instanceof SendingOnClosedConnection) {
|
|
8411
|
-
} else {
|
|
8558
|
+
if (err instanceof SendingOnClosedConnection) {} else {
|
|
8412
8559
|
throw err;
|
|
8413
8560
|
}
|
|
8414
8561
|
}
|
|
@@ -8420,7 +8567,7 @@ var __defProp2, __export2 = (target, all) => {
|
|
|
8420
8567
|
this.relay.idleSince = Date.now();
|
|
8421
8568
|
this.onclose?.(reason);
|
|
8422
8569
|
}
|
|
8423
|
-
}, _WebSocket, _WebSocket2, nip19_exports, NostrTypeGuard, Bech32MaxSize = 5000, BECH32_REGEX, nip04_exports, nip05_exports, NIP05_REGEX, isNip05 = (value) => NIP05_REGEX.test(value || ""), _fetch, nip10_exports, nip11_exports, _fetch2, nip13_exports, nip17_exports, nip59_exports, nip44_exports, minPlaintextSize = 1, maxPlaintextSize =
|
|
8570
|
+
}, _WebSocket, _WebSocket2, nip19_exports, NostrTypeGuard, Bech32MaxSize = 5000, BECH32_REGEX, nip04_exports, nip05_exports, NIP05_REGEX, isNip05 = (value) => NIP05_REGEX.test(value || ""), _fetch, nip10_exports, nip11_exports, _fetch2, nip13_exports, nip17_exports, nip59_exports, nip44_exports, minPlaintextSize = 1, maxPlaintextSize = 4294967295, extendedPrefixThreshold = 65536, v2, TWO_DAYS, now = () => Math.round(Date.now() / 1000), randomNow = () => Math.round(now() - Math.random() * TWO_DAYS), nip44ConversationKey = (privateKey, publicKey) => getConversationKey(privateKey, publicKey), nip44Encrypt = (data, privateKey, publicKey) => encrypt22(JSON.stringify(data), nip44ConversationKey(privateKey, publicKey)), nip44Decrypt = (data, privateKey) => JSON.parse(decrypt22(data.content, nip44ConversationKey(privateKey, data.pubkey))), unwrapEvent2, unwrapManyEvents2, nip18_exports, nip21_exports, NOSTR_URI_REGEX, nip22_exports, nip25_exports, nip27_exports, noCharacter, noURLCharacter, MAX_HASHTAG_LENGTH = 42, nip28_exports, channelCreateEvent = (t, privateKey) => {
|
|
8424
8571
|
let content;
|
|
8425
8572
|
if (typeof t.content === "object") {
|
|
8426
8573
|
content = JSON.stringify(t.content);
|
|
@@ -9087,12 +9234,10 @@ var init_esm = __esm(() => {
|
|
|
9087
9234
|
};
|
|
9088
9235
|
try {
|
|
9089
9236
|
_WebSocket = WebSocket;
|
|
9090
|
-
} catch {
|
|
9091
|
-
}
|
|
9237
|
+
} catch {}
|
|
9092
9238
|
try {
|
|
9093
9239
|
_WebSocket2 = WebSocket;
|
|
9094
|
-
} catch {
|
|
9095
|
-
}
|
|
9240
|
+
} catch {}
|
|
9096
9241
|
nip19_exports = {};
|
|
9097
9242
|
__export2(nip19_exports, {
|
|
9098
9243
|
BECH32_REGEX: () => BECH32_REGEX,
|
|
@@ -9135,8 +9280,7 @@ var init_esm = __esm(() => {
|
|
|
9135
9280
|
NIP05_REGEX = /^(?:([\w.+-]+)@)?([\w_-]+(\.[\w_-]+)+)$/;
|
|
9136
9281
|
try {
|
|
9137
9282
|
_fetch = fetch;
|
|
9138
|
-
} catch (_) {
|
|
9139
|
-
}
|
|
9283
|
+
} catch (_) {}
|
|
9140
9284
|
nip10_exports = {};
|
|
9141
9285
|
__export2(nip10_exports, {
|
|
9142
9286
|
parse: () => parse
|
|
@@ -9148,8 +9292,7 @@ var init_esm = __esm(() => {
|
|
|
9148
9292
|
});
|
|
9149
9293
|
try {
|
|
9150
9294
|
_fetch2 = fetch;
|
|
9151
|
-
} catch {
|
|
9152
|
-
}
|
|
9295
|
+
} catch {}
|
|
9153
9296
|
nip13_exports = {};
|
|
9154
9297
|
__export2(nip13_exports, {
|
|
9155
9298
|
getPow: () => getPow,
|
|
@@ -9182,7 +9325,9 @@ var init_esm = __esm(() => {
|
|
|
9182
9325
|
v2 = {
|
|
9183
9326
|
utils: {
|
|
9184
9327
|
getConversationKey,
|
|
9185
|
-
calcPaddedLen
|
|
9328
|
+
calcPaddedLen,
|
|
9329
|
+
pad,
|
|
9330
|
+
unpad
|
|
9186
9331
|
},
|
|
9187
9332
|
encrypt: encrypt22,
|
|
9188
9333
|
decrypt: decrypt22
|
|
@@ -9203,6 +9348,10 @@ var init_esm = __esm(() => {
|
|
|
9203
9348
|
test: () => test
|
|
9204
9349
|
});
|
|
9205
9350
|
NOSTR_URI_REGEX = new RegExp(`nostr:(${BECH32_REGEX.source})`);
|
|
9351
|
+
nip22_exports = {};
|
|
9352
|
+
__export2(nip22_exports, {
|
|
9353
|
+
parse: () => parse3
|
|
9354
|
+
});
|
|
9206
9355
|
nip25_exports = {};
|
|
9207
9356
|
__export2(nip25_exports, {
|
|
9208
9357
|
finishReactionEvent: () => finishReactionEvent,
|
|
@@ -9210,7 +9359,7 @@ var init_esm = __esm(() => {
|
|
|
9210
9359
|
});
|
|
9211
9360
|
nip27_exports = {};
|
|
9212
9361
|
__export2(nip27_exports, {
|
|
9213
|
-
parse: () =>
|
|
9362
|
+
parse: () => parse4
|
|
9214
9363
|
});
|
|
9215
9364
|
noCharacter = /\W/m;
|
|
9216
9365
|
noURLCharacter = /[^\w\/] |[^\w\/]$|$|,| /m;
|
|
@@ -9237,8 +9386,7 @@ var init_esm = __esm(() => {
|
|
|
9237
9386
|
});
|
|
9238
9387
|
try {
|
|
9239
9388
|
_fetch3 = fetch;
|
|
9240
|
-
} catch {
|
|
9241
|
-
}
|
|
9389
|
+
} catch {}
|
|
9242
9390
|
nip47_exports = {};
|
|
9243
9391
|
__export2(nip47_exports, {
|
|
9244
9392
|
makeNwcRequestEvent: () => makeNwcRequestEvent,
|
|
@@ -9259,8 +9407,7 @@ var init_esm = __esm(() => {
|
|
|
9259
9407
|
});
|
|
9260
9408
|
try {
|
|
9261
9409
|
_fetch4 = fetch;
|
|
9262
|
-
} catch {
|
|
9263
|
-
}
|
|
9410
|
+
} catch {}
|
|
9264
9411
|
nip77_exports = {};
|
|
9265
9412
|
__export2(nip77_exports, {
|
|
9266
9413
|
Negentropy: () => Negentropy,
|
|
@@ -9383,15 +9530,19 @@ async function loadConfig() {
|
|
|
9383
9530
|
function getDaemonBaseUrl(config) {
|
|
9384
9531
|
return config.daemonUrl?.replace(/\/$/, "") || `http://localhost:${config.port}`;
|
|
9385
9532
|
}
|
|
9386
|
-
|
|
9533
|
+
function getAuthBaseUrl(config) {
|
|
9534
|
+
if (config.authUrl) {
|
|
9535
|
+
return config.authUrl.replace(/\/$/, "");
|
|
9536
|
+
}
|
|
9537
|
+
return getDaemonBaseUrl(config);
|
|
9538
|
+
}
|
|
9539
|
+
async function _callUrl(baseUrl, path, options, config) {
|
|
9387
9540
|
const { method = "GET", body } = options;
|
|
9388
|
-
const config = await loadConfig();
|
|
9389
|
-
const baseUrl = getDaemonBaseUrl(config);
|
|
9390
9541
|
const url = `${baseUrl}${path}`;
|
|
9391
9542
|
const bodyString = body ? JSON.stringify(body) : undefined;
|
|
9392
9543
|
const bodyBytes = bodyString ? new TextEncoder().encode(bodyString) : undefined;
|
|
9393
9544
|
let authorization;
|
|
9394
|
-
if (config.daemonUrl && config.nsec) {
|
|
9545
|
+
if ((config.daemonUrl || config.authUrl) && config.nsec) {
|
|
9395
9546
|
const secretKey = parseSecretKey(config.nsec);
|
|
9396
9547
|
authorization = await createNIP98Authorization(secretKey, url, method, bodyBytes);
|
|
9397
9548
|
}
|
|
@@ -9409,6 +9560,16 @@ async function callDaemon(path, options = {}) {
|
|
|
9409
9560
|
}
|
|
9410
9561
|
return response.json();
|
|
9411
9562
|
}
|
|
9563
|
+
async function callDaemon(path, options = {}) {
|
|
9564
|
+
const config = await loadConfig();
|
|
9565
|
+
const baseUrl = getDaemonBaseUrl(config);
|
|
9566
|
+
return _callUrl(baseUrl, path, options, config);
|
|
9567
|
+
}
|
|
9568
|
+
async function callAuth(path, options = {}) {
|
|
9569
|
+
const config = await loadConfig();
|
|
9570
|
+
const baseUrl = getAuthBaseUrl(config);
|
|
9571
|
+
return _callUrl(baseUrl, path, options, config);
|
|
9572
|
+
}
|
|
9412
9573
|
async function isDaemonRunning() {
|
|
9413
9574
|
try {
|
|
9414
9575
|
const config = await loadConfig();
|
|
@@ -11269,8 +11430,8 @@ var require_qrcode = __commonJS((exports) => {
|
|
|
11269
11430
|
|
|
11270
11431
|
// node_modules/pngjs/lib/chunkstream.js
|
|
11271
11432
|
var require_chunkstream = __commonJS((exports, module) => {
|
|
11272
|
-
var util =
|
|
11273
|
-
var Stream =
|
|
11433
|
+
var util = __require("util");
|
|
11434
|
+
var Stream = __require("stream");
|
|
11274
11435
|
var ChunkStream = module.exports = function() {
|
|
11275
11436
|
Stream.call(this);
|
|
11276
11437
|
this._buffers = [];
|
|
@@ -11626,7 +11787,7 @@ var require_filter_parse = __commonJS((exports, module) => {
|
|
|
11626
11787
|
|
|
11627
11788
|
// node_modules/pngjs/lib/filter-parse-async.js
|
|
11628
11789
|
var require_filter_parse_async = __commonJS((exports, module) => {
|
|
11629
|
-
var util =
|
|
11790
|
+
var util = __require("util");
|
|
11630
11791
|
var ChunkStream = require_chunkstream();
|
|
11631
11792
|
var Filter = require_filter_parse();
|
|
11632
11793
|
var FilterAsync = module.exports = function(bitmapInfo) {
|
|
@@ -11740,8 +11901,7 @@ var require_parser = __commonJS((exports, module) => {
|
|
|
11740
11901
|
this.inflateData = dependencies.inflateData;
|
|
11741
11902
|
this.finished = dependencies.finished;
|
|
11742
11903
|
this.simpleTransparency = dependencies.simpleTransparency;
|
|
11743
|
-
this.headersFinished = dependencies.headersFinished || function() {
|
|
11744
|
-
};
|
|
11904
|
+
this.headersFinished = dependencies.headersFinished || function() {};
|
|
11745
11905
|
};
|
|
11746
11906
|
Parser.prototype.start = function() {
|
|
11747
11907
|
this.read(constants.PNG_SIGNATURE.length, this._parseSignature.bind(this));
|
|
@@ -11933,8 +12093,7 @@ var require_parser = __commonJS((exports, module) => {
|
|
|
11933
12093
|
var require_bitmapper = __commonJS((exports) => {
|
|
11934
12094
|
var interlaceUtils = require_interlace();
|
|
11935
12095
|
var pixelBppMapper = [
|
|
11936
|
-
function() {
|
|
11937
|
-
},
|
|
12096
|
+
function() {},
|
|
11938
12097
|
function(pxData, data, pxPos, rawPos) {
|
|
11939
12098
|
if (rawPos === data.length) {
|
|
11940
12099
|
throw new Error("Ran out of data");
|
|
@@ -11975,8 +12134,7 @@ var require_bitmapper = __commonJS((exports) => {
|
|
|
11975
12134
|
}
|
|
11976
12135
|
];
|
|
11977
12136
|
var pixelBppCustomMapper = [
|
|
11978
|
-
function() {
|
|
11979
|
-
},
|
|
12137
|
+
function() {},
|
|
11980
12138
|
function(pxData, pixelData, pxPos, maxBit) {
|
|
11981
12139
|
let pixel = pixelData[0];
|
|
11982
12140
|
pxData[pxPos] = pixel;
|
|
@@ -12220,8 +12378,8 @@ var require_format_normaliser = __commonJS((exports, module) => {
|
|
|
12220
12378
|
|
|
12221
12379
|
// node_modules/pngjs/lib/parser-async.js
|
|
12222
12380
|
var require_parser_async = __commonJS((exports, module) => {
|
|
12223
|
-
var util =
|
|
12224
|
-
var zlib =
|
|
12381
|
+
var util = __require("util");
|
|
12382
|
+
var zlib = __require("zlib");
|
|
12225
12383
|
var ChunkStream = require_chunkstream();
|
|
12226
12384
|
var FilterAsync = require_filter_parse_async();
|
|
12227
12385
|
var Parser = require_parser();
|
|
@@ -12255,8 +12413,7 @@ var require_parser_async = __commonJS((exports, module) => {
|
|
|
12255
12413
|
}
|
|
12256
12414
|
if (this._filter) {
|
|
12257
12415
|
this._filter.destroy();
|
|
12258
|
-
this._filter.on("error", function() {
|
|
12259
|
-
});
|
|
12416
|
+
this._filter.on("error", function() {});
|
|
12260
12417
|
}
|
|
12261
12418
|
this.errord = true;
|
|
12262
12419
|
};
|
|
@@ -12615,7 +12772,7 @@ var require_packer = __commonJS((exports, module) => {
|
|
|
12615
12772
|
var CrcStream = require_crc();
|
|
12616
12773
|
var bitPacker = require_bitpacker();
|
|
12617
12774
|
var filter = require_filter_pack();
|
|
12618
|
-
var zlib =
|
|
12775
|
+
var zlib = __require("zlib");
|
|
12619
12776
|
var Packer = module.exports = function(options) {
|
|
12620
12777
|
this._options = options;
|
|
12621
12778
|
options.deflateChunkSize = options.deflateChunkSize || 32 * 1024;
|
|
@@ -12699,8 +12856,8 @@ var require_packer = __commonJS((exports, module) => {
|
|
|
12699
12856
|
|
|
12700
12857
|
// node_modules/pngjs/lib/packer-async.js
|
|
12701
12858
|
var require_packer_async = __commonJS((exports, module) => {
|
|
12702
|
-
var util =
|
|
12703
|
-
var Stream =
|
|
12859
|
+
var util = __require("util");
|
|
12860
|
+
var Stream = __require("stream");
|
|
12704
12861
|
var constants = require_constants();
|
|
12705
12862
|
var Packer = require_packer();
|
|
12706
12863
|
var PackerAsync = module.exports = function(opt) {
|
|
@@ -12732,10 +12889,10 @@ var require_packer_async = __commonJS((exports, module) => {
|
|
|
12732
12889
|
|
|
12733
12890
|
// node_modules/pngjs/lib/sync-inflate.js
|
|
12734
12891
|
var require_sync_inflate = __commonJS((exports, module) => {
|
|
12735
|
-
var assert =
|
|
12736
|
-
var zlib =
|
|
12737
|
-
var util =
|
|
12738
|
-
var kMaxLength =
|
|
12892
|
+
var assert = __require("assert").ok;
|
|
12893
|
+
var zlib = __require("zlib");
|
|
12894
|
+
var util = __require("util");
|
|
12895
|
+
var kMaxLength = __require("buffer").kMaxLength;
|
|
12739
12896
|
function Inflate(opts) {
|
|
12740
12897
|
if (!(this instanceof Inflate)) {
|
|
12741
12898
|
return new Inflate(opts);
|
|
@@ -12895,8 +13052,7 @@ var require_filter_parse_sync = __commonJS((exports) => {
|
|
|
12895
13052
|
write: function(bufferPart) {
|
|
12896
13053
|
outBuffers.push(bufferPart);
|
|
12897
13054
|
},
|
|
12898
|
-
complete: function() {
|
|
12899
|
-
}
|
|
13055
|
+
complete: function() {}
|
|
12900
13056
|
});
|
|
12901
13057
|
filter.start();
|
|
12902
13058
|
reader.process();
|
|
@@ -12907,7 +13063,7 @@ var require_filter_parse_sync = __commonJS((exports) => {
|
|
|
12907
13063
|
// node_modules/pngjs/lib/parser-sync.js
|
|
12908
13064
|
var require_parser_sync = __commonJS((exports, module) => {
|
|
12909
13065
|
var hasSyncZlib = true;
|
|
12910
|
-
var zlib =
|
|
13066
|
+
var zlib = __require("zlib");
|
|
12911
13067
|
var inflateSync = require_sync_inflate();
|
|
12912
13068
|
if (!zlib.deflateSync) {
|
|
12913
13069
|
hasSyncZlib = false;
|
|
@@ -12993,7 +13149,7 @@ var require_parser_sync = __commonJS((exports, module) => {
|
|
|
12993
13149
|
// node_modules/pngjs/lib/packer-sync.js
|
|
12994
13150
|
var require_packer_sync = __commonJS((exports, module) => {
|
|
12995
13151
|
var hasSyncZlib = true;
|
|
12996
|
-
var zlib =
|
|
13152
|
+
var zlib = __require("zlib");
|
|
12997
13153
|
if (!zlib.deflateSync) {
|
|
12998
13154
|
hasSyncZlib = false;
|
|
12999
13155
|
}
|
|
@@ -13025,10 +13181,10 @@ var require_packer_sync = __commonJS((exports, module) => {
|
|
|
13025
13181
|
|
|
13026
13182
|
// node_modules/pngjs/lib/png-sync.js
|
|
13027
13183
|
var require_png_sync = __commonJS((exports) => {
|
|
13028
|
-
var
|
|
13184
|
+
var parse5 = require_parser_sync();
|
|
13029
13185
|
var pack = require_packer_sync();
|
|
13030
13186
|
exports.read = function(buffer, options) {
|
|
13031
|
-
return
|
|
13187
|
+
return parse5(buffer, options || {});
|
|
13032
13188
|
};
|
|
13033
13189
|
exports.write = function(png, options) {
|
|
13034
13190
|
return pack(png, options);
|
|
@@ -13037,8 +13193,8 @@ var require_png_sync = __commonJS((exports) => {
|
|
|
13037
13193
|
|
|
13038
13194
|
// node_modules/pngjs/lib/png.js
|
|
13039
13195
|
var require_png = __commonJS((exports) => {
|
|
13040
|
-
var util =
|
|
13041
|
-
var Stream =
|
|
13196
|
+
var util = __require("util");
|
|
13197
|
+
var Stream = __require("stream");
|
|
13042
13198
|
var Parser = require_parser_async();
|
|
13043
13199
|
var Packer = require_packer_async();
|
|
13044
13200
|
var PNGSync = require_png_sync();
|
|
@@ -13242,7 +13398,7 @@ var require_utils2 = __commonJS((exports) => {
|
|
|
13242
13398
|
|
|
13243
13399
|
// node_modules/qrcode/lib/renderer/png.js
|
|
13244
13400
|
var require_png2 = __commonJS((exports) => {
|
|
13245
|
-
var fs =
|
|
13401
|
+
var fs = __require("fs");
|
|
13246
13402
|
var PNG = require_png().PNG;
|
|
13247
13403
|
var Utils = require_utils2();
|
|
13248
13404
|
exports.render = function render(qrData, options) {
|
|
@@ -13366,7 +13522,7 @@ var require_utf8 = __commonJS((exports) => {
|
|
|
13366
13522
|
cb = options;
|
|
13367
13523
|
options = undefined;
|
|
13368
13524
|
}
|
|
13369
|
-
const fs =
|
|
13525
|
+
const fs = __require("fs");
|
|
13370
13526
|
const utf8 = exports.render(qrData, options);
|
|
13371
13527
|
fs.writeFile(path, utf8, cb);
|
|
13372
13528
|
};
|
|
@@ -13540,7 +13696,7 @@ var require_svg = __commonJS((exports) => {
|
|
|
13540
13696
|
cb = options;
|
|
13541
13697
|
options = undefined;
|
|
13542
13698
|
}
|
|
13543
|
-
const fs =
|
|
13699
|
+
const fs = __require("fs");
|
|
13544
13700
|
const svgTag = exports.render(qrData, options);
|
|
13545
13701
|
const xmlStr = '<?xml version="1.0" encoding="utf-8"?>' + '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">' + svgTag;
|
|
13546
13702
|
fs.writeFile(path, xmlStr, cb);
|
|
@@ -14157,8 +14313,7 @@ function renderBox(lines, width, title) {
|
|
|
14157
14313
|
function startBarSection(sectionKey, maxLabelLen) {
|
|
14158
14314
|
_sectionMaxLabelLen.set(sectionKey, maxLabelLen);
|
|
14159
14315
|
}
|
|
14160
|
-
function endBarSection(_sectionKey) {
|
|
14161
|
-
}
|
|
14316
|
+
function endBarSection(_sectionKey) {}
|
|
14162
14317
|
function renderBarChart(label, value, maxValue, width, color, percentageValue, sectionKey) {
|
|
14163
14318
|
const safeMaxValue = Math.max(maxValue, 1);
|
|
14164
14319
|
const pct = percentageValue !== undefined ? percentageValue.toFixed(1) : (value / safeMaxValue * 100).toFixed(1);
|
|
@@ -14925,7 +15080,6 @@ init_logger();
|
|
|
14925
15080
|
import { join as join3 } from "path";
|
|
14926
15081
|
|
|
14927
15082
|
// src/integrations/opencode.ts
|
|
14928
|
-
init_logger();
|
|
14929
15083
|
init_daemon_client();
|
|
14930
15084
|
import { existsSync as existsSync3, mkdirSync } from "fs";
|
|
14931
15085
|
import { readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
@@ -14933,9 +15087,9 @@ import { dirname as dirname2 } from "path";
|
|
|
14933
15087
|
var OPENCODE_SMALL_MODEL = "routstr/minimax-m2.5";
|
|
14934
15088
|
async function installOpencodeIntegration(config, apiKey, integrationConfig) {
|
|
14935
15089
|
const { name, configPath } = integrationConfig;
|
|
14936
|
-
|
|
15090
|
+
console.log(`
|
|
14937
15091
|
Installing routstr models in opencode.json...`);
|
|
14938
|
-
|
|
15092
|
+
console.log(`Using API key for ${name}`);
|
|
14939
15093
|
const baseUrl = getDaemonBaseUrl(config);
|
|
14940
15094
|
let opencodeConfig;
|
|
14941
15095
|
try {
|
|
@@ -14956,7 +15110,7 @@ Installing routstr models in opencode.json...`);
|
|
|
14956
15110
|
const data = await callDaemon("/models");
|
|
14957
15111
|
const models = data.output?.models || [];
|
|
14958
15112
|
if (models.length === 0) {
|
|
14959
|
-
|
|
15113
|
+
console.log("No models found from routstr daemon.");
|
|
14960
15114
|
return;
|
|
14961
15115
|
}
|
|
14962
15116
|
const modelsObj = {};
|
|
@@ -14975,23 +15129,22 @@ Installing routstr models in opencode.json...`);
|
|
|
14975
15129
|
};
|
|
14976
15130
|
opencodeConfig.small_model = OPENCODE_SMALL_MODEL;
|
|
14977
15131
|
await writeFile2(configPath, JSON.stringify(opencodeConfig, null, 2));
|
|
14978
|
-
|
|
15132
|
+
console.log(`Added "routstr" provider with ${models.length} models to opencode.json`);
|
|
14979
15133
|
} catch (error) {
|
|
14980
|
-
|
|
15134
|
+
console.error("Failed to install models in opencode.json:", error);
|
|
14981
15135
|
}
|
|
14982
15136
|
}
|
|
14983
15137
|
|
|
14984
15138
|
// src/integrations/pi.ts
|
|
14985
|
-
init_logger();
|
|
14986
15139
|
init_daemon_client();
|
|
14987
15140
|
import { existsSync as existsSync4, mkdirSync as mkdirSync2 } from "fs";
|
|
14988
15141
|
import { readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
|
|
14989
15142
|
import { dirname as dirname3 } from "path";
|
|
14990
15143
|
async function installPiIntegration(config, apiKey, integrationConfig) {
|
|
14991
15144
|
const { name, configPath } = integrationConfig;
|
|
14992
|
-
|
|
15145
|
+
console.log(`
|
|
14993
15146
|
Installing routstr models in pi models.json...`);
|
|
14994
|
-
|
|
15147
|
+
console.log(`Using API key for ${name}`);
|
|
14995
15148
|
const baseUrl = `${getDaemonBaseUrl(config)}/v1`;
|
|
14996
15149
|
let piConfig = {};
|
|
14997
15150
|
try {
|
|
@@ -15010,12 +15163,16 @@ Installing routstr models in pi models.json...`);
|
|
|
15010
15163
|
const data = await callDaemon("/models");
|
|
15011
15164
|
const models = data.output?.models || [];
|
|
15012
15165
|
if (models.length === 0) {
|
|
15013
|
-
|
|
15166
|
+
console.log("No models found from routstr daemon.");
|
|
15014
15167
|
return;
|
|
15015
15168
|
}
|
|
15016
|
-
const providerModels = models.map((model) =>
|
|
15017
|
-
id: model.id
|
|
15018
|
-
|
|
15169
|
+
const providerModels = models.map((model) => {
|
|
15170
|
+
const entry = { id: model.id };
|
|
15171
|
+
if (model.context_length !== undefined && model.context_length > 0) {
|
|
15172
|
+
entry.contextWindow = model.context_length;
|
|
15173
|
+
}
|
|
15174
|
+
return entry;
|
|
15175
|
+
});
|
|
15019
15176
|
piConfig.providers["routstr"] = {
|
|
15020
15177
|
baseUrl,
|
|
15021
15178
|
api: "openai-completions",
|
|
@@ -15023,14 +15180,13 @@ Installing routstr models in pi models.json...`);
|
|
|
15023
15180
|
models: providerModels
|
|
15024
15181
|
};
|
|
15025
15182
|
await writeFile3(configPath, JSON.stringify(piConfig, null, 2));
|
|
15026
|
-
|
|
15183
|
+
console.log(`Added "routstr" provider with ${models.length} models to pi models.json`);
|
|
15027
15184
|
} catch (error) {
|
|
15028
|
-
|
|
15185
|
+
console.error("Failed to install models in pi models.json:", error);
|
|
15029
15186
|
}
|
|
15030
15187
|
}
|
|
15031
15188
|
|
|
15032
15189
|
// src/integrations/openclaw.ts
|
|
15033
|
-
init_logger();
|
|
15034
15190
|
init_daemon_client();
|
|
15035
15191
|
import { existsSync as existsSync5, mkdirSync as mkdirSync3 } from "fs";
|
|
15036
15192
|
import { readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
|
|
@@ -15040,9 +15196,9 @@ var OPENCLAW_DEFAULT_PRIMARY_MODEL = "routstr/minimax-m2.5";
|
|
|
15040
15196
|
var OPENCLAW_DEFAULT_FALLBACK_MODEL = "routstr/kimi-k2.5";
|
|
15041
15197
|
async function installOpenClawIntegration(config, apiKey, integrationConfig) {
|
|
15042
15198
|
const { name, configPath } = integrationConfig;
|
|
15043
|
-
|
|
15199
|
+
console.log(`
|
|
15044
15200
|
Installing routstr models in openclaw.json...`);
|
|
15045
|
-
|
|
15201
|
+
console.log(`Using API key for ${name}`);
|
|
15046
15202
|
const baseUrl = getDaemonBaseUrl(config);
|
|
15047
15203
|
let openclawConfig = {};
|
|
15048
15204
|
try {
|
|
@@ -15070,7 +15226,7 @@ Installing routstr models in openclaw.json...`);
|
|
|
15070
15226
|
const data = await callDaemon("/models");
|
|
15071
15227
|
const models = data.output?.models || [];
|
|
15072
15228
|
if (models.length === 0) {
|
|
15073
|
-
|
|
15229
|
+
console.log("No models found from routstr daemon.");
|
|
15074
15230
|
return;
|
|
15075
15231
|
}
|
|
15076
15232
|
const providerModels = models.map((model) => ({
|
|
@@ -15099,23 +15255,22 @@ Installing routstr models in openclaw.json...`);
|
|
|
15099
15255
|
};
|
|
15100
15256
|
}
|
|
15101
15257
|
await writeFile4(configPath, JSON.stringify(openclawConfig, null, 2));
|
|
15102
|
-
|
|
15258
|
+
console.log(`Added "${OPENCLAW_PROVIDER_ID}" provider with ${models.length} models to openclaw.json`);
|
|
15103
15259
|
} catch (error) {
|
|
15104
|
-
|
|
15260
|
+
console.error("Failed to install models in openclaw.json:", error);
|
|
15105
15261
|
}
|
|
15106
15262
|
}
|
|
15107
15263
|
|
|
15108
15264
|
// src/integrations/claudecode.ts
|
|
15109
|
-
init_logger();
|
|
15110
15265
|
init_daemon_client();
|
|
15111
15266
|
import { existsSync as existsSync6, mkdirSync as mkdirSync4 } from "fs";
|
|
15112
15267
|
import { readFile as readFile5, writeFile as writeFile5 } from "fs/promises";
|
|
15113
15268
|
import { dirname as dirname5 } from "path";
|
|
15114
15269
|
async function installClaudeCodeIntegration(config, apiKey, integrationConfig) {
|
|
15115
15270
|
const { name, configPath } = integrationConfig;
|
|
15116
|
-
|
|
15271
|
+
console.log(`
|
|
15117
15272
|
Installing routstr configuration in ${configPath}...`);
|
|
15118
|
-
|
|
15273
|
+
console.log(`Using API key for ${name}`);
|
|
15119
15274
|
const baseUrl = getDaemonBaseUrl(config);
|
|
15120
15275
|
let settings = {};
|
|
15121
15276
|
try {
|
|
@@ -15124,7 +15279,7 @@ Installing routstr configuration in ${configPath}...`);
|
|
|
15124
15279
|
settings = JSON.parse(content);
|
|
15125
15280
|
}
|
|
15126
15281
|
} catch (error) {
|
|
15127
|
-
|
|
15282
|
+
console.error(`Error reading ${configPath}, creating new one.`);
|
|
15128
15283
|
}
|
|
15129
15284
|
if (!settings.env) {
|
|
15130
15285
|
settings.env = {};
|
|
@@ -15141,39 +15296,38 @@ Installing routstr configuration in ${configPath}...`);
|
|
|
15141
15296
|
settings.env["ANTHROPIC_DEFAULT_OPUS_MODEL"] = opus.id;
|
|
15142
15297
|
settings.env["ANTHROPIC_DEFAULT_SONNET_MODEL"] = sonnet.id;
|
|
15143
15298
|
settings.env["ANTHROPIC_DEFAULT_HAIKU_MODEL"] = haiku.id;
|
|
15144
|
-
|
|
15299
|
+
console.log(`Set Claude models: Opus=${opus.id}, Sonnet=${sonnet.id}, Haiku=${haiku.id}`);
|
|
15145
15300
|
} else if (models.length > 0) {
|
|
15146
15301
|
const model = models[0];
|
|
15147
|
-
|
|
15302
|
+
console.log(`Only ${models.length} models available, falling back to defaults.`);
|
|
15148
15303
|
settings.env["ANTHROPIC_DEFAULT_OPUS_MODEL"] = model.id;
|
|
15149
15304
|
settings.env["ANTHROPIC_DEFAULT_SONNET_MODEL"] = model.id;
|
|
15150
15305
|
settings.env["ANTHROPIC_DEFAULT_HAIKU_MODEL"] = model.id;
|
|
15151
15306
|
} else {
|
|
15152
|
-
|
|
15307
|
+
console.log("No models available from routstr daemon.");
|
|
15153
15308
|
}
|
|
15154
15309
|
} catch (error) {
|
|
15155
|
-
|
|
15310
|
+
console.error("Failed to fetch models for Claude Code integration:", error);
|
|
15156
15311
|
}
|
|
15157
15312
|
try {
|
|
15158
15313
|
mkdirSync4(dirname5(configPath), { recursive: true });
|
|
15159
15314
|
await writeFile5(configPath, JSON.stringify(settings, null, 2));
|
|
15160
|
-
|
|
15315
|
+
console.log(`Successfully updated ${configPath} with routstr settings.`);
|
|
15161
15316
|
} catch (error) {
|
|
15162
|
-
|
|
15317
|
+
console.error(`Failed to write to ${configPath}:`, error);
|
|
15163
15318
|
}
|
|
15164
15319
|
}
|
|
15165
15320
|
|
|
15166
15321
|
// src/integrations/hermes.ts
|
|
15167
|
-
init_logger();
|
|
15168
15322
|
init_daemon_client();
|
|
15169
15323
|
import { existsSync as existsSync7, mkdirSync as mkdirSync5 } from "fs";
|
|
15170
15324
|
import { readFile as readFile6, writeFile as writeFile6 } from "fs/promises";
|
|
15171
15325
|
import { dirname as dirname6 } from "path";
|
|
15172
15326
|
async function installHermesIntegration(config, apiKey, integrationConfig) {
|
|
15173
15327
|
const { name, configPath } = integrationConfig;
|
|
15174
|
-
|
|
15328
|
+
console.log(`
|
|
15175
15329
|
Installing routstr configuration in ${configPath}...`);
|
|
15176
|
-
|
|
15330
|
+
console.log(`Using API key for ${name}`);
|
|
15177
15331
|
const baseUrl = getDaemonBaseUrl(config);
|
|
15178
15332
|
const baseUrlV1 = `${baseUrl}/v1`;
|
|
15179
15333
|
let defaultModel = "minimax-m2.7";
|
|
@@ -15182,16 +15336,16 @@ Installing routstr configuration in ${configPath}...`);
|
|
|
15182
15336
|
const models = data.output?.models || [];
|
|
15183
15337
|
if (models.length >= 3) {
|
|
15184
15338
|
defaultModel = models[2].id;
|
|
15185
|
-
|
|
15339
|
+
console.log(`Set default model to 3rd available model: ${defaultModel}`);
|
|
15186
15340
|
} else if (models.length > 0) {
|
|
15187
15341
|
defaultModel = models[0].id;
|
|
15188
|
-
|
|
15342
|
+
console.log(`Only ${models.length} models available, using ${defaultModel} as default.`);
|
|
15189
15343
|
} else {
|
|
15190
|
-
|
|
15344
|
+
console.log("No models available from routstr daemon, using fallback default.");
|
|
15191
15345
|
}
|
|
15192
15346
|
} catch (error) {
|
|
15193
|
-
|
|
15194
|
-
|
|
15347
|
+
console.error("Failed to fetch models for Hermes integration:", error);
|
|
15348
|
+
console.log("Using fallback default model.");
|
|
15195
15349
|
}
|
|
15196
15350
|
let content = "";
|
|
15197
15351
|
try {
|
|
@@ -15199,7 +15353,7 @@ Installing routstr configuration in ${configPath}...`);
|
|
|
15199
15353
|
content = await readFile6(configPath, "utf-8");
|
|
15200
15354
|
}
|
|
15201
15355
|
} catch (error) {
|
|
15202
|
-
|
|
15356
|
+
console.error(`Error reading ${configPath}, creating new one.`);
|
|
15203
15357
|
}
|
|
15204
15358
|
content = content.replace(/^model:\n(?: .*\n)*/gm, "");
|
|
15205
15359
|
content = content.replace(/^custom_providers:\n(?:- .*\n(?: .*\n)*)*/gm, "");
|
|
@@ -15229,9 +15383,9 @@ Installing routstr configuration in ${configPath}...`);
|
|
|
15229
15383
|
try {
|
|
15230
15384
|
mkdirSync5(dirname6(configPath), { recursive: true });
|
|
15231
15385
|
await writeFile6(configPath, newContent);
|
|
15232
|
-
|
|
15386
|
+
console.log(`Successfully updated ${configPath} with routstr settings.`);
|
|
15233
15387
|
} catch (error) {
|
|
15234
|
-
|
|
15388
|
+
console.error(`Failed to write to ${configPath}:`, error);
|
|
15235
15389
|
}
|
|
15236
15390
|
}
|
|
15237
15391
|
|
|
@@ -15286,7 +15440,7 @@ async function runIntegrationsForClients(clientIds, config) {
|
|
|
15286
15440
|
|
|
15287
15441
|
// src/utils/clients.ts
|
|
15288
15442
|
async function getClientsList() {
|
|
15289
|
-
const result = await
|
|
15443
|
+
const result = await callAuth("/clients");
|
|
15290
15444
|
const clients = result.output?.clients;
|
|
15291
15445
|
if (!clients) {
|
|
15292
15446
|
return [];
|
|
@@ -15315,7 +15469,7 @@ async function addDaemonClient(name) {
|
|
|
15315
15469
|
};
|
|
15316
15470
|
return { client, created: false };
|
|
15317
15471
|
}
|
|
15318
|
-
const result = await
|
|
15472
|
+
const result = await callAuth("/clients/add", {
|
|
15319
15473
|
method: "POST",
|
|
15320
15474
|
body: { name, id: derivedId }
|
|
15321
15475
|
});
|
|
@@ -15353,7 +15507,7 @@ async function listClientsAction() {
|
|
|
15353
15507
|
}
|
|
15354
15508
|
async function deleteClientAction(id) {
|
|
15355
15509
|
await ensureDaemonRunning();
|
|
15356
|
-
const result = await
|
|
15510
|
+
const result = await callAuth("/clients/delete", {
|
|
15357
15511
|
method: "POST",
|
|
15358
15512
|
body: { id }
|
|
15359
15513
|
});
|
|
@@ -15477,14 +15631,14 @@ function parseChoice(input) {
|
|
|
15477
15631
|
return 1;
|
|
15478
15632
|
}
|
|
15479
15633
|
async function setupIntegration(config) {
|
|
15480
|
-
|
|
15634
|
+
console.log(`
|
|
15481
15635
|
Choose an integration to set up:`);
|
|
15482
|
-
|
|
15483
|
-
|
|
15484
|
-
|
|
15485
|
-
|
|
15486
|
-
|
|
15487
|
-
|
|
15636
|
+
console.log("1. OpenCode (default)");
|
|
15637
|
+
console.log("2. OpenClaw");
|
|
15638
|
+
console.log("3. Pi");
|
|
15639
|
+
console.log("4. Claude Code");
|
|
15640
|
+
console.log("5. Hermes");
|
|
15641
|
+
console.log("6. Skip for now");
|
|
15488
15642
|
const answer = await ask("Select integration [1]: ");
|
|
15489
15643
|
const choice = parseChoice(answer);
|
|
15490
15644
|
const integrationByChoice = {
|
|
@@ -15496,15 +15650,15 @@ Choose an integration to set up:`);
|
|
|
15496
15650
|
};
|
|
15497
15651
|
const key = integrationByChoice[choice];
|
|
15498
15652
|
if (!key) {
|
|
15499
|
-
|
|
15653
|
+
console.log("Skipping integration setup.");
|
|
15500
15654
|
return;
|
|
15501
15655
|
}
|
|
15502
15656
|
const integrationConfig = CLIENT_CONFIGS[key];
|
|
15503
15657
|
const { client, created } = await addDaemonClient(integrationConfig.name);
|
|
15504
15658
|
if (created) {
|
|
15505
|
-
|
|
15659
|
+
console.log(`Created new API key for ${integrationConfig.name}`);
|
|
15506
15660
|
} else {
|
|
15507
|
-
|
|
15661
|
+
console.log(`Using existing API key for ${integrationConfig.name}`);
|
|
15508
15662
|
}
|
|
15509
15663
|
if (key === "opencode") {
|
|
15510
15664
|
await installOpencodeIntegration(config, client.apiKey, integrationConfig);
|
|
@@ -15629,7 +15783,7 @@ async function isCocodInstalled(cocodPath) {
|
|
|
15629
15783
|
// package.json
|
|
15630
15784
|
var package_default = {
|
|
15631
15785
|
name: "routstrd",
|
|
15632
|
-
version: "0.
|
|
15786
|
+
version: "0.3.1",
|
|
15633
15787
|
module: "src/index.ts",
|
|
15634
15788
|
type: "module",
|
|
15635
15789
|
private: false,
|
|
@@ -15653,9 +15807,10 @@ var package_default = {
|
|
|
15653
15807
|
},
|
|
15654
15808
|
dependencies: {
|
|
15655
15809
|
"@cashu/cashu-ts": "^4.3.0",
|
|
15656
|
-
"@routstr/sdk": "^0.3.
|
|
15810
|
+
"@routstr/sdk": "^0.3.9",
|
|
15657
15811
|
"applesauce-core": "^5.1.0",
|
|
15658
15812
|
"applesauce-relay": "^5.1.0",
|
|
15813
|
+
"applesauce-wallet-connect": "^6.0.0",
|
|
15659
15814
|
commander: "^14.0.2",
|
|
15660
15815
|
"nostr-tools": "^2.12.0",
|
|
15661
15816
|
qrcode: "^1.5.4",
|
|
@@ -15687,17 +15842,17 @@ Invoice:
|
|
|
15687
15842
|
${invoice}`);
|
|
15688
15843
|
}
|
|
15689
15844
|
async function installCocodOrExit() {
|
|
15690
|
-
|
|
15845
|
+
console.log("cocod not found. Installing globally with bun...");
|
|
15691
15846
|
const installProc = Bun.spawn(["bun", "install", "--global", "@routstr/cocod"], {
|
|
15692
15847
|
stdout: "inherit",
|
|
15693
15848
|
stderr: "inherit"
|
|
15694
15849
|
});
|
|
15695
15850
|
const installCode = await installProc.exited;
|
|
15696
15851
|
if (installCode !== 0 || !await isCocodInstalled()) {
|
|
15697
|
-
|
|
15852
|
+
console.error("Failed to install cocod. Please run 'bun install --global @routstr/cocod' manually.");
|
|
15698
15853
|
throw new Error("cocod installation failed");
|
|
15699
15854
|
}
|
|
15700
|
-
|
|
15855
|
+
console.log("cocod installed successfully.");
|
|
15701
15856
|
}
|
|
15702
15857
|
async function requireLocalDaemon() {
|
|
15703
15858
|
const config = await loadConfig();
|
|
@@ -15707,10 +15862,10 @@ async function requireLocalDaemon() {
|
|
|
15707
15862
|
}
|
|
15708
15863
|
}
|
|
15709
15864
|
async function initDaemon() {
|
|
15710
|
-
|
|
15865
|
+
console.log("Initializing routstrd...");
|
|
15711
15866
|
if (!existsSync9(CONFIG_DIR)) {
|
|
15712
15867
|
mkdirSync6(CONFIG_DIR, { recursive: true });
|
|
15713
|
-
|
|
15868
|
+
console.log(`Created config directory: ${CONFIG_DIR}`);
|
|
15714
15869
|
}
|
|
15715
15870
|
if (!existsSync9(CONFIG_FILE)) {
|
|
15716
15871
|
const config2 = {
|
|
@@ -15718,7 +15873,7 @@ async function initDaemon() {
|
|
|
15718
15873
|
cocodPath: null
|
|
15719
15874
|
};
|
|
15720
15875
|
await Bun.write(CONFIG_FILE, JSON.stringify(config2, null, 2));
|
|
15721
|
-
|
|
15876
|
+
console.log(`Created config file: ${CONFIG_FILE}`);
|
|
15722
15877
|
}
|
|
15723
15878
|
const config = await loadConfig();
|
|
15724
15879
|
if (!await isCocodInstalled(config.cocodPath)) {
|
|
@@ -15761,27 +15916,27 @@ Initializing cocod...`);
|
|
|
15761
15916
|
${initStderr}`.toLowerCase();
|
|
15762
15917
|
const alreadyInitialized = combinedOutput.includes("already initialized");
|
|
15763
15918
|
if (initCode !== 0 && !alreadyInitialized) {
|
|
15764
|
-
|
|
15919
|
+
console.error("Failed to initialize cocod. Please run 'cocod init' manually.");
|
|
15765
15920
|
return;
|
|
15766
15921
|
}
|
|
15767
15922
|
if (alreadyInitialized) {
|
|
15768
|
-
|
|
15923
|
+
console.log("cocod is already initialized.");
|
|
15769
15924
|
} else {
|
|
15770
|
-
|
|
15925
|
+
console.log("cocod initialized successfully.");
|
|
15771
15926
|
}
|
|
15772
15927
|
await startDaemon({ port: String(config.port || 8008) });
|
|
15773
15928
|
await setupIntegration(config);
|
|
15774
|
-
|
|
15929
|
+
console.log(`
|
|
15775
15930
|
Initialization complete!`);
|
|
15776
|
-
|
|
15931
|
+
console.log(`
|
|
15777
15932
|
use 'routstrd receive <cashu-token>' or 'routstrd receive 2100' to top up your local wallet using Lightning!`);
|
|
15778
|
-
|
|
15933
|
+
console.log(`
|
|
15779
15934
|
full wallet commands still work too, e.g. 'routstrd wallet receive cashu <token>' and 'routstrd wallet receive bolt11 2100'.`);
|
|
15780
|
-
|
|
15935
|
+
console.log(`
|
|
15781
15936
|
To ensure routstrd persists across system restarts, run: 'routstrd service install'`);
|
|
15782
15937
|
}
|
|
15783
15938
|
program.name("routstrd").description("Routstr daemon - Manage routstr processes").version(package_default.version, "--version", "output the version number");
|
|
15784
|
-
program.command("refund").description("Refund pending tokens and API keys to a specified mint").option("-m, --mint-url <mintUrl>", "Mint URL to refund to (defaults to first mint in wallet)").option("-y, --yes", "Skip confirmation prompt", false).action(async (options) => {
|
|
15939
|
+
program.command("refund").description("Refund pending tokens and API keys to a specified mint").option("-m, --mint-url <mintUrl>", "Mint URL to refund to (defaults to first mint in wallet)").option("-y, --yes", "Skip confirmation prompt", false).option("--xcashu", "Refund xcashu tokens only (uses refundXcashuTokens)", false).action(async (options) => {
|
|
15785
15940
|
await ensureDaemonRunning();
|
|
15786
15941
|
let mintUrl = options.mintUrl;
|
|
15787
15942
|
if (!mintUrl) {
|
|
@@ -15799,6 +15954,27 @@ program.command("refund").description("Refund pending tokens and API keys to a s
|
|
|
15799
15954
|
console.log(`Using mint URL: ${mintUrl}`);
|
|
15800
15955
|
}
|
|
15801
15956
|
try {
|
|
15957
|
+
if (options.xcashu) {
|
|
15958
|
+
const result2 = await callDaemon("/refund/xcashu", {
|
|
15959
|
+
method: "POST",
|
|
15960
|
+
body: { mintUrl }
|
|
15961
|
+
});
|
|
15962
|
+
if (result2.error) {
|
|
15963
|
+
console.log(result2.error);
|
|
15964
|
+
process.exit(1);
|
|
15965
|
+
}
|
|
15966
|
+
const output2 = result2.output;
|
|
15967
|
+
if (output2) {
|
|
15968
|
+
console.log(output2.message);
|
|
15969
|
+
console.log(`
|
|
15970
|
+
Results:`);
|
|
15971
|
+
for (const r of output2.results) {
|
|
15972
|
+
const status = r.success ? "success" : `failed: ${r.error || "unknown"}`;
|
|
15973
|
+
console.log(` - ${r.baseUrl}: ${status}`);
|
|
15974
|
+
}
|
|
15975
|
+
}
|
|
15976
|
+
return;
|
|
15977
|
+
}
|
|
15802
15978
|
const result = await callDaemon("/refund", {
|
|
15803
15979
|
method: "POST",
|
|
15804
15980
|
body: { mintUrl }
|
|
@@ -15829,18 +16005,29 @@ Results:`);
|
|
|
15829
16005
|
process.exit(1);
|
|
15830
16006
|
}
|
|
15831
16007
|
});
|
|
15832
|
-
program.command("remote <url>").description("Configure a remote daemon URL").action(async (url) => {
|
|
16008
|
+
program.command("remote <url>").description("Configure a remote daemon URL").option("--auth-url <authUrl>", "URL of the auth proxy for management commands (npubs, clients, usage)").action(async (url, options) => {
|
|
15833
16009
|
try {
|
|
15834
16010
|
new URL(url);
|
|
15835
16011
|
} catch {
|
|
15836
16012
|
console.error(`Invalid URL: ${url}`);
|
|
15837
16013
|
process.exit(1);
|
|
15838
16014
|
}
|
|
16015
|
+
if (options.authUrl) {
|
|
16016
|
+
try {
|
|
16017
|
+
new URL(options.authUrl);
|
|
16018
|
+
} catch {
|
|
16019
|
+
console.error(`Invalid auth URL: ${options.authUrl}`);
|
|
16020
|
+
process.exit(1);
|
|
16021
|
+
}
|
|
16022
|
+
}
|
|
15839
16023
|
if (!existsSync9(CONFIG_DIR)) {
|
|
15840
16024
|
mkdirSync6(CONFIG_DIR, { recursive: true });
|
|
15841
16025
|
}
|
|
15842
16026
|
const config = await loadConfig();
|
|
15843
16027
|
const updates = { daemonUrl: url };
|
|
16028
|
+
if (options.authUrl) {
|
|
16029
|
+
updates.authUrl = options.authUrl;
|
|
16030
|
+
}
|
|
15844
16031
|
let generatedNpub;
|
|
15845
16032
|
if (!config.nsec) {
|
|
15846
16033
|
const secretKey = generateSecretKey();
|
|
@@ -15855,6 +16042,9 @@ program.command("remote <url>").description("Configure a remote daemon URL").act
|
|
|
15855
16042
|
};
|
|
15856
16043
|
await Bun.write(CONFIG_FILE, JSON.stringify(updatedConfig, null, 2));
|
|
15857
16044
|
console.log(`Remote daemon URL set to: ${url}`);
|
|
16045
|
+
if (options.authUrl) {
|
|
16046
|
+
console.log(`Auth proxy URL set to: ${options.authUrl}`);
|
|
16047
|
+
}
|
|
15858
16048
|
if (generatedNpub) {
|
|
15859
16049
|
console.log(`
|
|
15860
16050
|
A new Nostr identity has been generated for remote authentication.`);
|
|
@@ -16032,7 +16222,7 @@ program.command("usage").description("Show recent usage logs and total sats cost
|
|
|
16032
16222
|
await ensureDaemonRunning();
|
|
16033
16223
|
const requested = Number.parseInt(options.limit, 10);
|
|
16034
16224
|
const limit = Number.isFinite(requested) && requested > 0 ? Math.min(requested, 1000) : 10;
|
|
16035
|
-
const result = await
|
|
16225
|
+
const result = await callAuth(`/usage?limit=${limit}`);
|
|
16036
16226
|
if (result.error) {
|
|
16037
16227
|
console.log(result.error);
|
|
16038
16228
|
process.exit(1);
|
|
@@ -16139,7 +16329,7 @@ npubsCmd.command("list").description("List configured npubs with their roles").a
|
|
|
16139
16329
|
await ensureDaemonRunning();
|
|
16140
16330
|
const config = await loadConfig();
|
|
16141
16331
|
const userNpub = getUserNpub(config);
|
|
16142
|
-
const result = await
|
|
16332
|
+
const result = await callAuth("/npubs");
|
|
16143
16333
|
if (result.error) {
|
|
16144
16334
|
console.log(result.error);
|
|
16145
16335
|
process.exit(1);
|
|
@@ -16172,7 +16362,7 @@ npubsCmd.command("register").description("Register yourself as the first admin (
|
|
|
16172
16362
|
console.error("No Nostr identity configured. Run 'routstrd remote <url>' to set one up.");
|
|
16173
16363
|
process.exit(1);
|
|
16174
16364
|
}
|
|
16175
|
-
const result = await
|
|
16365
|
+
const result = await callAuth("/npubs");
|
|
16176
16366
|
if (result.error) {
|
|
16177
16367
|
console.log(result.error);
|
|
16178
16368
|
process.exit(1);
|
|
@@ -16189,7 +16379,7 @@ npubsCmd.command("register").description("Register yourself as the first admin (
|
|
|
16189
16379
|
console.error("Failed to normalize user npub.");
|
|
16190
16380
|
process.exit(1);
|
|
16191
16381
|
}
|
|
16192
|
-
const addResult = await
|
|
16382
|
+
const addResult = await callAuth("/npubs", {
|
|
16193
16383
|
method: "POST",
|
|
16194
16384
|
body: { npub: npubFromPubkey(normalized) }
|
|
16195
16385
|
});
|
|
@@ -16216,7 +16406,7 @@ npubsCmd.command("add <npub>").description("Add a npub (hex pubkey or npub1...).
|
|
|
16216
16406
|
process.exit(1);
|
|
16217
16407
|
}
|
|
16218
16408
|
const body = { npub: npubFromPubkey(normalized), role: options.role };
|
|
16219
|
-
const result = await
|
|
16409
|
+
const result = await callAuth("/npubs", {
|
|
16220
16410
|
method: "POST",
|
|
16221
16411
|
body
|
|
16222
16412
|
});
|
|
@@ -16240,7 +16430,7 @@ npubsCmd.command("update <npub>").description("Update the role of an existing np
|
|
|
16240
16430
|
console.error("Invalid role. Expected 'admin' or 'user'.");
|
|
16241
16431
|
process.exit(1);
|
|
16242
16432
|
}
|
|
16243
|
-
const result = await
|
|
16433
|
+
const result = await callAuth("/npubs", {
|
|
16244
16434
|
method: "PATCH",
|
|
16245
16435
|
body: { npub: npubFromPubkey(normalized), role: options.role }
|
|
16246
16436
|
});
|
|
@@ -16262,7 +16452,7 @@ npubsCmd.command("delete <npub>").description("Delete an npub (hex pubkey or npu
|
|
|
16262
16452
|
console.error("Invalid npub value. Use npub1... or 64-char hex pubkey.");
|
|
16263
16453
|
process.exit(1);
|
|
16264
16454
|
}
|
|
16265
|
-
const result = await
|
|
16455
|
+
const result = await callAuth(`/npubs/${encodeURIComponent(npubFromPubkey(normalized))}`, {
|
|
16266
16456
|
method: "DELETE"
|
|
16267
16457
|
});
|
|
16268
16458
|
if (result.error) {
|
|
@@ -16407,6 +16597,65 @@ walletMintsCmd.command("info <url>").description("Get wallet mint info").action(
|
|
|
16407
16597
|
body: { url }
|
|
16408
16598
|
});
|
|
16409
16599
|
});
|
|
16600
|
+
var nwcCmd = program.command("nwc").description("Manage NWC (Nostr Wallet Connect) integration");
|
|
16601
|
+
nwcCmd.command("connect").description("Connect to a Lightning wallet via NWC").argument("[connection-string]", "NWC connection string (nostr+walletconnect://...)").action(async (connectionString) => {
|
|
16602
|
+
if (!connectionString) {
|
|
16603
|
+
const rl = __require("readline").createInterface({
|
|
16604
|
+
input: process.stdin,
|
|
16605
|
+
output: process.stdout
|
|
16606
|
+
});
|
|
16607
|
+
connectionString = await new Promise((resolve) => {
|
|
16608
|
+
rl.question("Paste your NWC connection string: ", (answer) => {
|
|
16609
|
+
rl.close();
|
|
16610
|
+
resolve(answer.trim());
|
|
16611
|
+
});
|
|
16612
|
+
});
|
|
16613
|
+
}
|
|
16614
|
+
if (!/^nostr\+walletconnect:\/\/[0-9a-fA-F]{64}\?relay=/.test(connectionString)) {
|
|
16615
|
+
console.error("Invalid NWC connection string: expected nostr+walletconnect://<64-char-hex>?relay=...");
|
|
16616
|
+
process.exit(1);
|
|
16617
|
+
}
|
|
16618
|
+
await handleDaemonCommand("/nwc/connect", {
|
|
16619
|
+
method: "POST",
|
|
16620
|
+
body: { connectionString }
|
|
16621
|
+
});
|
|
16622
|
+
});
|
|
16623
|
+
nwcCmd.command("disconnect").description("Disconnect from NWC wallet").action(async () => {
|
|
16624
|
+
await handleDaemonCommand("/nwc/disconnect", {
|
|
16625
|
+
method: "POST"
|
|
16626
|
+
});
|
|
16627
|
+
});
|
|
16628
|
+
nwcCmd.command("status").description("Show NWC connection status and wallet info").action(async () => {
|
|
16629
|
+
await handleDaemonCommand("/nwc/status");
|
|
16630
|
+
});
|
|
16631
|
+
nwcCmd.command("fund <amount>").description("Manually fund the Cashu wallet from the connected NWC wallet").action(async (amount) => {
|
|
16632
|
+
const parsedAmount = parsePositiveIntOrExit(amount, "amount");
|
|
16633
|
+
await handleDaemonCommand("/nwc/fund", {
|
|
16634
|
+
method: "POST",
|
|
16635
|
+
body: { amount: parsedAmount }
|
|
16636
|
+
});
|
|
16637
|
+
});
|
|
16638
|
+
var autoRefillCmd = nwcCmd.command("auto-refill").description("Manage automatic wallet refill from NWC");
|
|
16639
|
+
autoRefillCmd.command("on").description("Enable auto-refill").option("--threshold <sats>", "Refill when Cashu balance drops below this many sats", "500").option("--amount <sats>", "Refill this many sats at a time", "1000").option("--cooldown <seconds>", "Minimum time between refills in seconds", "300").action(async (options) => {
|
|
16640
|
+
const threshold = parsePositiveIntOrExit(options.threshold, "threshold");
|
|
16641
|
+
const amount = parsePositiveIntOrExit(options.amount, "amount");
|
|
16642
|
+
const cooldownSec = parsePositiveIntOrExit(options.cooldown, "cooldown");
|
|
16643
|
+
await handleDaemonCommand("/nwc/auto-refill", {
|
|
16644
|
+
method: "POST",
|
|
16645
|
+
body: {
|
|
16646
|
+
enabled: true,
|
|
16647
|
+
threshold,
|
|
16648
|
+
amount,
|
|
16649
|
+
cooldownMs: cooldownSec * 1000
|
|
16650
|
+
}
|
|
16651
|
+
});
|
|
16652
|
+
});
|
|
16653
|
+
autoRefillCmd.command("off").description("Disable auto-refill").action(async () => {
|
|
16654
|
+
await handleDaemonCommand("/nwc/auto-refill", {
|
|
16655
|
+
method: "POST",
|
|
16656
|
+
body: { enabled: false }
|
|
16657
|
+
});
|
|
16658
|
+
});
|
|
16410
16659
|
program.command("stop").description("Stop the background daemon").action(async () => {
|
|
16411
16660
|
await handleDaemonCommand("/stop", { method: "POST" });
|
|
16412
16661
|
});
|
|
@@ -16428,7 +16677,7 @@ serviceCmd.command("install").description("Install and start routstrd using PM2
|
|
|
16428
16677
|
try {
|
|
16429
16678
|
daemonPath = Bun.resolveSync("./daemon/index.js", import.meta.url);
|
|
16430
16679
|
} catch (e) {
|
|
16431
|
-
const path =
|
|
16680
|
+
const path = __require("path");
|
|
16432
16681
|
daemonPath = path.join(path.dirname(import.meta.url).replace("file://", ""), "daemon", "index.js");
|
|
16433
16682
|
}
|
|
16434
16683
|
if (!existsSync9(daemonPath)) {
|
|
@@ -16465,8 +16714,7 @@ serviceCmd.command("uninstall").description("Stop and remove routstrd from PM2")
|
|
|
16465
16714
|
serviceCmd.command("logs").description("View PM2 logs for routstrd").action(() => {
|
|
16466
16715
|
try {
|
|
16467
16716
|
execSync("pm2 logs routstrd", { stdio: "inherit" });
|
|
16468
|
-
} catch (e) {
|
|
16469
|
-
}
|
|
16717
|
+
} catch (e) {}
|
|
16470
16718
|
});
|
|
16471
16719
|
program.command("restart").description("Restart the background daemon").option("--port <port>", "Port to listen on").option("-p, --provider <provider>", "Default provider to use").action(async (options) => {
|
|
16472
16720
|
await requireLocalDaemon();
|
|
@@ -16507,7 +16755,7 @@ program.command("mode").description("Set the client mode (lazyrefund/apikeys or
|
|
|
16507
16755
|
Current mode: ${currentMode}`);
|
|
16508
16756
|
const modes = ["apikeys", "xcashu"];
|
|
16509
16757
|
const selectedIndex = await new Promise((resolve) => {
|
|
16510
|
-
const rl =
|
|
16758
|
+
const rl = __require("readline").createInterface({
|
|
16511
16759
|
input: process.stdin,
|
|
16512
16760
|
output: process.stdout
|
|
16513
16761
|
});
|