@getalby/cli
Advanced tools
| import { discover } from "../tools/lightning/discover.js"; | ||
| import { handleError, output } from "../utils.js"; | ||
| export function registerDiscoverCommand(program) { | ||
| program | ||
| .command("discover") | ||
| .description("Search 402index.io for paid API services that accept bitcoin/lightning") | ||
| .option("-q, --query <text>", "Search query") | ||
| .option("-p, --protocol <protocol>", "Filter by protocol (L402, x402, MPP)") | ||
| .option("--health <status>", "Filter by health (healthy, degraded, down, unknown)", "healthy") | ||
| .option("-s, --sort <field>", "Sort by (reliability, latency, price, name)", "reliability") | ||
| .option("-l, --limit <number>", "Number of results", "10") | ||
| .action(async (options) => { | ||
| await handleError(async () => { | ||
| const result = await discover({ | ||
| query: options.query, | ||
| protocol: options.protocol, | ||
| health: options.health, | ||
| sort: options.sort, | ||
| limit: parseInt(options.limit, 10), | ||
| }); | ||
| output(result); | ||
| }); | ||
| }); | ||
| } |
| export async function discover(params) { | ||
| const url = new URL("https://402index.io/api/v1/services"); | ||
| const requestedLimit = params.limit ?? 10; | ||
| if (params.query) | ||
| url.searchParams.set("q", params.query); | ||
| if (params.protocol) | ||
| url.searchParams.set("protocol", params.protocol); | ||
| if (params.health) | ||
| url.searchParams.set("health", params.health); | ||
| if (params.sort) | ||
| url.searchParams.set("sort", params.sort); | ||
| // Filter to BTC (Lightning) services server-side | ||
| url.searchParams.set("payment_asset", "BTC"); | ||
| url.searchParams.set("limit", String(requestedLimit)); | ||
| const controller = new AbortController(); | ||
| const timer = setTimeout(() => controller.abort(), 5000); | ||
| let response; | ||
| try { | ||
| response = await fetch(url.toString(), { signal: controller.signal }); | ||
| } | ||
| catch (error) { | ||
| if (error instanceof Error && error.name === "AbortError") { | ||
| throw new Error("Request to 402index.io timed out"); | ||
| } | ||
| throw error; | ||
| } | ||
| finally { | ||
| clearTimeout(timer); | ||
| } | ||
| if (!response.ok) { | ||
| throw new Error(`402index.io returned status ${response.status}: ${await response.text()}`); | ||
| } | ||
| const data = (await response.json()); | ||
| return { | ||
| services: data.services.map((s) => ({ | ||
| name: s.name, | ||
| description: s.description, | ||
| url: s.url, | ||
| protocol: s.protocol, | ||
| price_sats: s.price_sats, | ||
| price_usd: s.price_usd, | ||
| category: s.category, | ||
| provider: s.provider, | ||
| health_status: s.health_status, | ||
| reliability_score: s.reliability_score, | ||
| latency_p50_ms: s.latency_p50_ms, | ||
| http_method: s.http_method, | ||
| })), | ||
| total: data.total, | ||
| }; | ||
| } |
+5
-1
@@ -25,2 +25,3 @@ #!/usr/bin/env node | ||
| import { registerAuthCommand } from "./commands/auth.js"; | ||
| import { registerDiscoverCommand } from "./commands/discover.js"; | ||
| const program = new Command(); | ||
@@ -36,3 +37,3 @@ program | ||
| " $ npx @getalby/cli pay-invoice --invoice lnbc...") | ||
| .version("0.5.0") | ||
| .version("0.6.0") | ||
| .option("-w, --wallet-name <name>", "Use a named wallet's connection secret (~/.alby-cli/connection-secret-<name>.key)") | ||
@@ -82,2 +83,5 @@ .option("-c, --connection-secret <string>", "NWC connection secret (nostr+walletconnect://...) or path to file containing it (preferred)") | ||
| registerFetch402Command(program); | ||
| // Register service discovery | ||
| program.commandsGroup("Service Discovery:"); | ||
| registerDiscoverCommand(program); | ||
| // Register setup commands | ||
@@ -84,0 +88,0 @@ program.commandsGroup("Setup:"); |
+1
-1
@@ -5,3 +5,3 @@ { | ||
| "repository": "https://github.com/getAlby/cli.git", | ||
| "version": "0.5.0", | ||
| "version": "0.6.0", | ||
| "type": "module", | ||
@@ -8,0 +8,0 @@ "main": "build/index.js", |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
78142
4.11%56
3.7%1419
5.9%5
25%