satgate 1.5.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.
Files changed (79) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +207 -0
  3. package/dist/bin/satgate.d.ts +3 -0
  4. package/dist/bin/satgate.d.ts.map +1 -0
  5. package/dist/bin/satgate.js +7 -0
  6. package/dist/bin/satgate.js.map +1 -0
  7. package/dist/src/auth/allowlist.d.ts +24 -0
  8. package/dist/src/auth/allowlist.d.ts.map +1 -0
  9. package/dist/src/auth/allowlist.js +130 -0
  10. package/dist/src/auth/allowlist.js.map +1 -0
  11. package/dist/src/auth/middleware.d.ts +15 -0
  12. package/dist/src/auth/middleware.d.ts.map +1 -0
  13. package/dist/src/auth/middleware.js +29 -0
  14. package/dist/src/auth/middleware.js.map +1 -0
  15. package/dist/src/cli.d.ts +2 -0
  16. package/dist/src/cli.d.ts.map +1 -0
  17. package/dist/src/cli.js +275 -0
  18. package/dist/src/cli.js.map +1 -0
  19. package/dist/src/config.d.ts +133 -0
  20. package/dist/src/config.d.ts.map +1 -0
  21. package/dist/src/config.js +237 -0
  22. package/dist/src/config.js.map +1 -0
  23. package/dist/src/discovery/llms-txt.d.ts +10 -0
  24. package/dist/src/discovery/llms-txt.d.ts.map +1 -0
  25. package/dist/src/discovery/llms-txt.js +25 -0
  26. package/dist/src/discovery/llms-txt.js.map +1 -0
  27. package/dist/src/discovery/openapi.d.ts +8 -0
  28. package/dist/src/discovery/openapi.d.ts.map +1 -0
  29. package/dist/src/discovery/openapi.js +116 -0
  30. package/dist/src/discovery/openapi.js.map +1 -0
  31. package/dist/src/discovery/well-known.d.ts +22 -0
  32. package/dist/src/discovery/well-known.d.ts.map +1 -0
  33. package/dist/src/discovery/well-known.js +44 -0
  34. package/dist/src/discovery/well-known.js.map +1 -0
  35. package/dist/src/index.d.ts +15 -0
  36. package/dist/src/index.d.ts.map +1 -0
  37. package/dist/src/index.js +15 -0
  38. package/dist/src/index.js.map +1 -0
  39. package/dist/src/lightning.d.ts +12 -0
  40. package/dist/src/lightning.d.ts.map +1 -0
  41. package/dist/src/lightning.js +38 -0
  42. package/dist/src/lightning.js.map +1 -0
  43. package/dist/src/logger.d.ts +16 -0
  44. package/dist/src/logger.d.ts.map +1 -0
  45. package/dist/src/logger.js +99 -0
  46. package/dist/src/logger.js.map +1 -0
  47. package/dist/src/proxy/capacity.d.ts +15 -0
  48. package/dist/src/proxy/capacity.d.ts.map +1 -0
  49. package/dist/src/proxy/capacity.js +28 -0
  50. package/dist/src/proxy/capacity.js.map +1 -0
  51. package/dist/src/proxy/handler.d.ts +27 -0
  52. package/dist/src/proxy/handler.d.ts.map +1 -0
  53. package/dist/src/proxy/handler.js +165 -0
  54. package/dist/src/proxy/handler.js.map +1 -0
  55. package/dist/src/proxy/pricing.d.ts +17 -0
  56. package/dist/src/proxy/pricing.d.ts.map +1 -0
  57. package/dist/src/proxy/pricing.js +42 -0
  58. package/dist/src/proxy/pricing.js.map +1 -0
  59. package/dist/src/proxy/streaming.d.ts +12 -0
  60. package/dist/src/proxy/streaming.d.ts.map +1 -0
  61. package/dist/src/proxy/streaming.js +68 -0
  62. package/dist/src/proxy/streaming.js.map +1 -0
  63. package/dist/src/proxy/token-counter.d.ts +22 -0
  64. package/dist/src/proxy/token-counter.d.ts.map +1 -0
  65. package/dist/src/proxy/token-counter.js +66 -0
  66. package/dist/src/proxy/token-counter.js.map +1 -0
  67. package/dist/src/server.d.ts +9 -0
  68. package/dist/src/server.d.ts.map +1 -0
  69. package/dist/src/server.js +239 -0
  70. package/dist/src/server.js.map +1 -0
  71. package/dist/src/tunnel.d.ts +26 -0
  72. package/dist/src/tunnel.d.ts.map +1 -0
  73. package/dist/src/tunnel.js +78 -0
  74. package/dist/src/tunnel.js.map +1 -0
  75. package/dist/src/x402/facilitator.d.ts +7 -0
  76. package/dist/src/x402/facilitator.d.ts.map +1 -0
  77. package/dist/src/x402/facilitator.js +33 -0
  78. package/dist/src/x402/facilitator.js.map +1 -0
  79. package/package.json +70 -0
@@ -0,0 +1,239 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { fileURLToPath } from 'node:url';
3
+ import { dirname, join } from 'node:path';
4
+ import { Hono } from 'hono';
5
+ import { createTollBooth, createX402Rail, memoryStorage, sqliteStorage, } from '@thecryptodonkey/toll-booth';
6
+ import { createHonoTollBooth } from '@thecryptodonkey/toll-booth/hono';
7
+ import { createNoopLogger } from './logger.js';
8
+ import { createAuthMiddleware } from './auth/middleware.js';
9
+ import { createProxyHandler } from './proxy/handler.js';
10
+ import { CapacityTracker } from './proxy/capacity.js';
11
+ import { generateWellKnown } from './discovery/well-known.js';
12
+ import { generateLlmsTxt } from './discovery/llms-txt.js';
13
+ import { generateOpenApiSpec } from './discovery/openapi.js';
14
+ import { createHttpFacilitator } from './x402/facilitator.js';
15
+ /**
16
+ * Sanitise upstream /v1/models response — only forward id + object fields.
17
+ * Prevents leaking internal upstream metadata (e.g. paths, owners, permissions).
18
+ */
19
+ function sanitiseModelsResponse(body) {
20
+ if (!body || typeof body !== 'object')
21
+ return { data: [] };
22
+ const raw = body.data;
23
+ if (!Array.isArray(raw))
24
+ return { data: [] };
25
+ const data = raw
26
+ .filter((m) => typeof m === 'object' && m !== null && typeof m.id === 'string')
27
+ .map(m => ({ id: m.id, object: 'model' }));
28
+ return { object: 'list', data };
29
+ }
30
+ export function createTokenTollServer(config) {
31
+ const logger = config.logger ?? createNoopLogger();
32
+ const app = new Hono();
33
+ const capacity = new CapacityTracker(config.capacity.maxConcurrent);
34
+ // Security headers on every response
35
+ app.use('*', async (c, next) => {
36
+ await next();
37
+ c.header('X-Content-Type-Options', 'nosniff');
38
+ c.header('X-Frame-Options', 'DENY');
39
+ c.header('Referrer-Policy', 'no-referrer');
40
+ c.header('X-Download-Options', 'noopen');
41
+ c.header('Strict-Transport-Security', 'max-age=63072000; includeSubDomains');
42
+ });
43
+ // Create storage
44
+ const storage = config.storage === 'sqlite'
45
+ ? sqliteStorage({ path: config.dbPath })
46
+ : memoryStorage();
47
+ // Build payment rails
48
+ const rails = [];
49
+ if (config.x402) {
50
+ const facilitator = config.x402.facilitatorUrl
51
+ ? createHttpFacilitator({
52
+ facilitatorUrl: config.x402.facilitatorUrl,
53
+ facilitatorKey: config.x402.facilitatorKey,
54
+ })
55
+ : undefined;
56
+ if (facilitator) {
57
+ rails.push(createX402Rail({
58
+ receiverAddress: config.x402.receiverAddress,
59
+ network: config.x402.network,
60
+ asset: config.x402.asset,
61
+ facilitator,
62
+ creditMode: config.x402.creditMode ?? true,
63
+ facilitatorUrl: config.x402.facilitatorUrl,
64
+ storage,
65
+ }));
66
+ }
67
+ }
68
+ // Dual-currency pricing entry
69
+ const pricingEntry = config.defaultPriceUsd !== undefined
70
+ ? { sats: config.estimatedCostSats, usd: config.defaultPriceUsd }
71
+ : config.estimatedCostSats;
72
+ // Create toll-booth engine
73
+ const engine = createTollBooth({
74
+ rootKey: config.rootKey,
75
+ storage,
76
+ upstream: config.upstream,
77
+ backend: config.backend,
78
+ pricing: {
79
+ '/v1/chat/completions': pricingEntry,
80
+ '/v1/completions': pricingEntry,
81
+ '/v1/embeddings': pricingEntry,
82
+ },
83
+ defaultInvoiceAmount: config.tiers[0]?.amountSats ?? 1000,
84
+ freeTier: config.freeTier.creditsPerDay > 0 ? { creditsPerDay: config.freeTier.creditsPerDay } : undefined,
85
+ ...(rails.length > 0 && { rails }),
86
+ serviceName: config.serviceName,
87
+ onPayment: (e) => logger.payment(e),
88
+ onRequest: (e) => logger.request(e),
89
+ onChallenge: (e) => logger.challenge(e),
90
+ });
91
+ // Create Hono toll-booth adapter
92
+ const tollBooth = createHonoTollBooth({ engine });
93
+ // Mount payment routes
94
+ const paymentApp = tollBooth.createPaymentApp({
95
+ storage,
96
+ rootKey: config.rootKey,
97
+ tiers: config.tiers,
98
+ defaultAmount: config.tiers[0]?.amountSats ?? 1000,
99
+ backend: config.backend,
100
+ serviceName: config.serviceName,
101
+ });
102
+ app.route('/', paymentApp);
103
+ // Discoverability endpoints (no auth required)
104
+ const models = config.models ?? [];
105
+ const paymentMethods = ['lightning', 'cashu'];
106
+ if (config.x402)
107
+ paymentMethods.push('x402');
108
+ app.get('/.well-known/l402', (c) => {
109
+ return c.json(generateWellKnown({
110
+ pricing: config.pricing,
111
+ models,
112
+ tiers: config.tiers,
113
+ paymentMethods,
114
+ freeTier: config.freeTier,
115
+ x402: config.x402,
116
+ }));
117
+ });
118
+ app.get('/llms.txt', (c) => {
119
+ return c.text(generateLlmsTxt({
120
+ pricing: config.pricing,
121
+ models,
122
+ ...(config.x402 && { x402: { network: config.x402.network } }),
123
+ }));
124
+ });
125
+ app.get('/openapi.json', (c) => {
126
+ return c.json(generateOpenApiSpec({
127
+ models,
128
+ pricing: config.pricing,
129
+ x402: !!config.x402,
130
+ }));
131
+ });
132
+ // Health check
133
+ app.get('/health', (c) => {
134
+ return c.json({
135
+ status: 'ok',
136
+ models,
137
+ activeRequests: capacity.active,
138
+ maxConcurrent: capacity.maxConcurrent,
139
+ });
140
+ });
141
+ // Landing page — try two locations:
142
+ // 1. Dev (tsx): __dirname is src/, so ../src/page/index.html → src/page/index.html
143
+ // 2. Docker (compiled): __dirname is dist/src/, so ../page/index.html → dist/page/index.html
144
+ const __dirname = dirname(fileURLToPath(import.meta.url));
145
+ const landingPagePaths = [
146
+ join(__dirname, '..', 'src', 'page', 'index.html'),
147
+ join(__dirname, '..', 'page', 'index.html'),
148
+ ];
149
+ let landingPageHtml;
150
+ for (const p of landingPagePaths) {
151
+ try {
152
+ landingPageHtml = readFileSync(p, 'utf-8');
153
+ break;
154
+ }
155
+ catch {
156
+ // Try next path
157
+ }
158
+ }
159
+ if (landingPageHtml) {
160
+ const html = landingPageHtml;
161
+ app.get('/', (c) => c.html(html));
162
+ }
163
+ // /v1/models passes through without auth — cached for 60s to prevent upstream amplification
164
+ let modelsCache;
165
+ app.get('/v1/models', async (c) => {
166
+ if (modelsCache && Date.now() < modelsCache.expires) {
167
+ return c.json(modelsCache.data);
168
+ }
169
+ try {
170
+ const res = await fetch(`${config.upstream}/v1/models`, {
171
+ signal: AbortSignal.timeout(10_000),
172
+ });
173
+ const body = await res.json();
174
+ // Sanitise upstream response — only forward model IDs, not arbitrary fields
175
+ const sanitised = sanitiseModelsResponse(body);
176
+ modelsCache = { data: sanitised, expires: Date.now() + 60_000 };
177
+ return c.json(sanitised);
178
+ }
179
+ catch {
180
+ return c.json({ data: [] });
181
+ }
182
+ });
183
+ // AI proxy routes (behind auth middleware)
184
+ const proxyHandler = createProxyHandler({
185
+ upstream: config.upstream,
186
+ pricing: config.pricing,
187
+ capacity,
188
+ reconcile: (paymentHash, actualCost) => engine.reconcile(paymentHash, actualCost),
189
+ maxBodySize: config.maxBodySize,
190
+ flatPricing: config.flatPricing,
191
+ logger,
192
+ });
193
+ if (config.authMode === 'lightning') {
194
+ app.use('/v1/*', tollBooth.authMiddleware);
195
+ }
196
+ else {
197
+ const authMiddleware = createAuthMiddleware({
198
+ authMode: config.authMode,
199
+ allowlist: config.allowlist,
200
+ });
201
+ app.use('/v1/*', authMiddleware);
202
+ }
203
+ // Forward toll-booth credit/free-tier context as response headers.
204
+ // Must run AFTER next() so c.header() applies to the actual response.
205
+ app.use('/v1/*', async (c, next) => {
206
+ await next();
207
+ const creditBalance = c.get('tollBoothCreditBalance');
208
+ if (creditBalance !== undefined) {
209
+ c.header('X-Credit-Balance', String(creditBalance));
210
+ }
211
+ const estimatedCost = c.get('tollBoothEstimatedCost');
212
+ if (estimatedCost !== undefined) {
213
+ c.header('X-Estimated-Cost', String(estimatedCost));
214
+ }
215
+ const freeRemaining = c.get('tollBoothFreeRemaining');
216
+ if (freeRemaining !== undefined) {
217
+ c.header('X-Free-Remaining', String(freeRemaining));
218
+ }
219
+ });
220
+ app.post('/v1/chat/completions', async (c) => {
221
+ const paymentHash = config.authMode === 'lightning' ? c.get('tollBoothPaymentHash') : undefined;
222
+ return proxyHandler(c.req.raw, paymentHash);
223
+ });
224
+ app.post('/v1/completions', async (c) => {
225
+ const paymentHash = config.authMode === 'lightning' ? c.get('tollBoothPaymentHash') : undefined;
226
+ return proxyHandler(c.req.raw, paymentHash);
227
+ });
228
+ app.post('/v1/embeddings', async (c) => {
229
+ const paymentHash = config.authMode === 'lightning' ? c.get('tollBoothPaymentHash') : undefined;
230
+ return proxyHandler(c.req.raw, paymentHash);
231
+ });
232
+ return {
233
+ app,
234
+ close: () => {
235
+ // Cleanup if needed
236
+ },
237
+ };
238
+ }
239
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { type ChildProcess } from 'node:child_process';
2
+ /**
3
+ * Check if cloudflared is available on PATH.
4
+ * Returns the path to the binary, or null if not found.
5
+ * Note: uses `which` — works on macOS/Linux, not Windows.
6
+ */
7
+ export declare function findCloudflared(): string | null;
8
+ /**
9
+ * Parse the tunnel URL from cloudflared's stderr output.
10
+ */
11
+ export declare function parseTunnelUrl(output: string): string | undefined;
12
+ export interface TunnelResult {
13
+ url?: string;
14
+ process?: ChildProcess;
15
+ error?: string;
16
+ }
17
+ /**
18
+ * Start a Cloudflare Tunnel pointing at the given local port.
19
+ * Resolves when the tunnel URL is available or after a 10s timeout.
20
+ */
21
+ export declare function startTunnel(port: number): Promise<TunnelResult>;
22
+ /**
23
+ * Gracefully stop the tunnel process.
24
+ */
25
+ export declare function stopTunnel(child: ChildProcess): void;
26
+ //# sourceMappingURL=tunnel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel.d.ts","sourceRoot":"","sources":["../../src/tunnel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAE3E;;;;GAIG;AACH,wBAAgB,eAAe,IAAI,MAAM,GAAG,IAAI,CAO/C;AAID;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGjE;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CA4C/D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAIpD"}
@@ -0,0 +1,78 @@
1
+ import { spawn, execFileSync } from 'node:child_process';
2
+ /**
3
+ * Check if cloudflared is available on PATH.
4
+ * Returns the path to the binary, or null if not found.
5
+ * Note: uses `which` — works on macOS/Linux, not Windows.
6
+ */
7
+ export function findCloudflared() {
8
+ try {
9
+ const result = execFileSync('which', ['cloudflared'], { encoding: 'utf-8', timeout: 5000 });
10
+ return result.trim() || null;
11
+ }
12
+ catch {
13
+ return null;
14
+ }
15
+ }
16
+ const TUNNEL_URL_RE = /https:\/\/[a-z0-9-]+\.trycloudflare\.com/;
17
+ /**
18
+ * Parse the tunnel URL from cloudflared's stderr output.
19
+ */
20
+ export function parseTunnelUrl(output) {
21
+ const match = output.match(TUNNEL_URL_RE);
22
+ return match?.[0];
23
+ }
24
+ /**
25
+ * Start a Cloudflare Tunnel pointing at the given local port.
26
+ * Resolves when the tunnel URL is available or after a 10s timeout.
27
+ */
28
+ export function startTunnel(port) {
29
+ const cloudflaredPath = findCloudflared();
30
+ if (!cloudflaredPath) {
31
+ return Promise.resolve({
32
+ error: 'cloudflared not found. Install: brew install cloudflared',
33
+ });
34
+ }
35
+ return new Promise((resolve) => {
36
+ const child = spawn(cloudflaredPath, ['tunnel', '--url', `http://localhost:${port}`], {
37
+ stdio: ['ignore', 'pipe', 'pipe'],
38
+ });
39
+ let stderr = '';
40
+ const MAX_STDERR = 64 * 1024; // 64 KiB cap to prevent unbounded memory growth
41
+ const timeout = setTimeout(() => {
42
+ if (!child.killed)
43
+ child.kill('SIGTERM');
44
+ resolve({ error: 'Tunnel startup timed out (10s)' });
45
+ }, 10_000);
46
+ child.stderr?.on('data', (chunk) => {
47
+ if (stderr.length < MAX_STDERR) {
48
+ stderr += chunk.toString();
49
+ if (stderr.length > MAX_STDERR)
50
+ stderr = stderr.slice(0, MAX_STDERR);
51
+ }
52
+ const url = parseTunnelUrl(stderr);
53
+ if (url) {
54
+ clearTimeout(timeout);
55
+ resolve({ url, process: child });
56
+ }
57
+ });
58
+ child.on('error', (err) => {
59
+ clearTimeout(timeout);
60
+ resolve({ error: `Failed to start cloudflared: ${err.message}` });
61
+ });
62
+ child.on('exit', (code) => {
63
+ clearTimeout(timeout);
64
+ if (code !== null && code !== 0) {
65
+ resolve({ error: `cloudflared exited with code ${code}` });
66
+ }
67
+ });
68
+ });
69
+ }
70
+ /**
71
+ * Gracefully stop the tunnel process.
72
+ */
73
+ export function stopTunnel(child) {
74
+ if (!child.killed) {
75
+ child.kill('SIGTERM');
76
+ }
77
+ }
78
+ //# sourceMappingURL=tunnel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel.js","sourceRoot":"","sources":["../../src/tunnel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { X402Facilitator } from '@thecryptodonkey/toll-booth';
2
+ export interface HttpFacilitatorConfig {
3
+ facilitatorUrl: string;
4
+ facilitatorKey?: string;
5
+ }
6
+ export declare function createHttpFacilitator(config: HttpFacilitatorConfig): X402Facilitator;
7
+ //# sourceMappingURL=facilitator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facilitator.d.ts","sourceRoot":"","sources":["../../../src/x402/facilitator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAiC,MAAM,6BAA6B,CAAA;AAEjG,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,MAAM,CAAA;IACtB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,qBAAqB,GAAG,eAAe,CAkCpF"}
@@ -0,0 +1,33 @@
1
+ export function createHttpFacilitator(config) {
2
+ return {
3
+ async verify(payload) {
4
+ const headers = {
5
+ 'Content-Type': 'application/json',
6
+ };
7
+ if (config.facilitatorKey) {
8
+ headers['Authorization'] = `Bearer ${config.facilitatorKey}`;
9
+ }
10
+ const res = await fetch(config.facilitatorUrl, {
11
+ method: 'POST',
12
+ headers,
13
+ body: JSON.stringify(payload),
14
+ signal: AbortSignal.timeout(10_000),
15
+ });
16
+ if (!res.ok) {
17
+ return { valid: false, txHash: '', amount: 0, sender: '' };
18
+ }
19
+ const result = await res.json();
20
+ // Validate response shape — don't trust arbitrary JSON from external facilitator
21
+ if (typeof result !== 'object' || result === null) {
22
+ return { valid: false, txHash: '', amount: 0, sender: '' };
23
+ }
24
+ return {
25
+ valid: result.valid === true,
26
+ txHash: typeof result.txHash === 'string' ? result.txHash : '',
27
+ amount: typeof result.amount === 'number' ? result.amount : 0,
28
+ sender: typeof result.sender === 'string' ? result.sender : '',
29
+ };
30
+ },
31
+ };
32
+ }
33
+ //# sourceMappingURL=facilitator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facilitator.js","sourceRoot":"","sources":["../../../src/x402/facilitator.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,qBAAqB,CAAC,MAA6B;IACjE,OAAO;QACL,KAAK,CAAC,MAAM,CAAC,OAAoB;YAC/B,MAAM,OAAO,GAA2B;gBACtC,cAAc,EAAE,kBAAkB;aACnC,CAAA;YACD,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;gBAC1B,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,MAAM,CAAC,cAAc,EAAE,CAAA;YAC9D,CAAC;YAED,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE;gBAC7C,MAAM,EAAE,MAAM;gBACd,OAAO;gBACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;gBAC7B,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;aACpC,CAAC,CAAA;YAEF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAA;YAC5D,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,EAA6B,CAAA;YAC1D,iFAAiF;YACjF,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;gBAClD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAA;YAC5D,CAAC;YACD,OAAO;gBACL,KAAK,EAAE,MAAM,CAAC,KAAK,KAAK,IAAI;gBAC5B,MAAM,EAAE,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;gBAC9D,MAAM,EAAE,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;gBAC7D,MAAM,EAAE,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;aAC/D,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "satgate",
3
+ "version": "1.5.1",
4
+ "description": "Lightning-paid AI inference - monetise any OpenAI-compatible endpoint in 30 seconds",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "bin": {
9
+ "satgate": "./dist/bin/satgate.js"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "default": "./dist/index.js"
15
+ }
16
+ },
17
+ "scripts": {
18
+ "build": "tsc",
19
+ "test": "vitest run",
20
+ "typecheck": "tsc --noEmit",
21
+ "dev": "tsx src/cli.ts",
22
+ "prepublishOnly": "npm run build"
23
+ },
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "engines": {
28
+ "node": ">=22.0.0"
29
+ },
30
+ "dependencies": {
31
+ "@hono/node-server": "^1.0.0",
32
+ "@noble/curves": "^2.0.1",
33
+ "@scure/base": "^2.0.0",
34
+ "@thecryptodonkey/toll-booth": "^2.0.0",
35
+ "hono": "^4.0.0",
36
+ "js-yaml": "^4.1.1"
37
+ },
38
+ "devDependencies": {
39
+ "@semantic-release/changelog": "^6.0.3",
40
+ "@semantic-release/git": "^10.0.1",
41
+ "@semantic-release/github": "^12.0.6",
42
+ "@types/js-yaml": "^4.0.9",
43
+ "@types/node": "^25.5.0",
44
+ "bolt11": "^1.4.1",
45
+ "l402-mcp": "file:../l402-mcp",
46
+ "semantic-release": "^25.0.3",
47
+ "tsx": "^4.0.0",
48
+ "typescript": "^5.8.0",
49
+ "vitest": "^3.1.0"
50
+ },
51
+ "keywords": [
52
+ "lightning",
53
+ "l402",
54
+ "ai",
55
+ "inference",
56
+ "llm",
57
+ "bitcoin",
58
+ "payments"
59
+ ],
60
+ "license": "MIT",
61
+ "repository": {
62
+ "type": "git",
63
+ "url": "https://github.com/TheCryptoDonkey/satgate"
64
+ },
65
+ "homepage": "https://github.com/TheCryptoDonkey/satgate",
66
+ "author": "TheCryptoDonkey",
67
+ "bugs": {
68
+ "url": "https://github.com/TheCryptoDonkey/satgate/issues"
69
+ }
70
+ }