2020117-agent 0.6.2 → 0.6.4

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/dist/agent.js CHANGED
@@ -22,6 +22,8 @@ for (const arg of process.argv.slice(2)) {
22
22
  if (eq === -1) {
23
23
  // Bare flags (no value)
24
24
  if (arg === '--sovereign') { } // legacy flag, all agents are now Nostr-native
25
+ if (arg === '--p2p-only')
26
+ process.env.P2P_ONLY = 'true';
25
27
  continue;
26
28
  }
27
29
  const key = arg.slice(0, eq);
@@ -72,12 +74,15 @@ for (const arg of process.argv.slice(2)) {
72
74
  case '--relays':
73
75
  process.env.NOSTR_RELAYS = val;
74
76
  break;
77
+ case '--p2p-only':
78
+ process.env.P2P_ONLY = val;
79
+ break;
75
80
  }
76
81
  }
77
82
  import { randomBytes } from 'crypto';
78
83
  import { SwarmNode, topicFromKind } from './swarm.js';
79
84
  import { createProcessor } from './processor.js';
80
- import { generateInvoice } from './clink.js';
85
+ import { generateInvoice } from './lnurl.js';
81
86
  import { generateKeypair, loadSovereignKeys, saveSovereignKeys, loadAgentName, signEvent, signEventWithPow, nip44Encrypt, nip44Decrypt, pubkeyFromPrivkey, RelayPool, } from './nostr.js';
82
87
  import { parseNwcUri, nwcGetBalance, nwcPayLightningAddress } from './nwc.js';
83
88
  import { readFileSync } from 'fs';
@@ -88,6 +93,7 @@ if (!globalThis.WebSocket)
88
93
  // --- Config from env ---
89
94
  const KIND = Number(process.env.DVM_KIND) || 5100;
90
95
  const MAX_CONCURRENT = Number(process.env.MAX_JOBS) || 3;
96
+ const P2P_ONLY = process.env.P2P_ONLY === 'true' || process.env.P2P_ONLY === '1';
91
97
  const SATS_PER_CHUNK = Number(process.env.SATS_PER_CHUNK) || 1;
92
98
  const CHUNKS_PER_PAYMENT = Number(process.env.CHUNKS_PER_PAYMENT) || 10;
93
99
  // --- Lightning payment config ---
@@ -246,11 +252,13 @@ async function setupNostr(label) {
246
252
  await publishProfile(label);
247
253
  // 5. Publish ai.info (Kind 31340) — NIP-XX capability advertisement
248
254
  await publishAiInfo(label);
249
- // 6. Publish handler info (Kind 31990) — NIP-89 DVM capability
255
+ // 6. Publish handler info (Kind 31990) — NIP-89 DVM capability (always, even P2P-only)
250
256
  await publishHandlerInfo(label);
251
257
  // 7. Subscribe to NIP-XX prompts (Kind 25802)
252
258
  subscribeNipXX(label);
253
- // 8. Subscribe to DVM requests (Kind 5xxx) directly from relay
259
+ // 8. Subscribe to DVM requests (Kind 5xxx)
260
+ // P2P-only: still subscribes but handleDvmRequest will ignore broadcast jobs,
261
+ // only responding to direct requests (p tag = our pubkey)
254
262
  subscribeDvmRequests(label);
255
263
  subscribeDvmResults(label);
256
264
  // 9. Start heartbeat (Kind 30333 to relay)
@@ -277,6 +285,7 @@ async function setupNostr(label) {
277
285
  console.log(` Lightning: ${LIGHTNING_ADDRESS || '(not set)'}`);
278
286
  console.log(` NWC wallet: ${state.nwcParsed ? 'connected' : '(not set)'}`);
279
287
  console.log(` Processor: ${state.processor?.name || 'none'}`);
288
+ console.log(` Mode: ${P2P_ONLY ? 'P2P-only (DVM disabled)' : 'DVM + P2P'}`);
280
289
  console.log(`═══════════════════════════════════════════════`);
281
290
  console.log('');
282
291
  }
@@ -542,6 +551,12 @@ async function handleDvmRequest(label, event) {
542
551
  // Skip own events
543
552
  if (event.pubkey === state.sovereignKeys.pubkey)
544
553
  return;
554
+ // P2P-only mode: only handle direct requests (p tag pointing to us)
555
+ if (P2P_ONLY) {
556
+ const isDirected = event.tags.some(t => t[0] === 'p' && t[1] === state.sovereignKeys.pubkey);
557
+ if (!isDirected)
558
+ return;
559
+ }
545
560
  // Dedup: skip already-seen events
546
561
  if (!markSeen(event.id))
547
562
  return;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Lightning payment utilities — invoice generation via LNURL-pay
3
+ *
4
+ * Provider generates invoices from their own Lightning Address.
5
+ * Customer pays invoices via NWC wallet.
6
+ */
7
+ /**
8
+ * Resolve a Lightning Address to a bolt11 invoice via LNURL-pay protocol.
9
+ * The provider calls this on their OWN Lightning Address to generate
10
+ * an invoice that pays themselves.
11
+ *
12
+ * Flow: address → .well-known/lnurlp → callback?amount= → bolt11
13
+ */
14
+ export declare function generateInvoice(lightningAddress: string, amountSats: number): Promise<string>;
package/dist/lnurl.js ADDED
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Lightning payment utilities — invoice generation via LNURL-pay
3
+ *
4
+ * Provider generates invoices from their own Lightning Address.
5
+ * Customer pays invoices via NWC wallet.
6
+ */
7
+ /**
8
+ * Resolve a Lightning Address to a bolt11 invoice via LNURL-pay protocol.
9
+ * The provider calls this on their OWN Lightning Address to generate
10
+ * an invoice that pays themselves.
11
+ *
12
+ * Flow: address → .well-known/lnurlp → callback?amount= → bolt11
13
+ */
14
+ export async function generateInvoice(lightningAddress, amountSats) {
15
+ const [user, domain] = lightningAddress.split('@');
16
+ if (!user || !domain)
17
+ throw new Error(`Invalid Lightning Address: ${lightningAddress}`);
18
+ // Step 1: Fetch LNURL-pay metadata
19
+ const metaUrl = `https://${domain}/.well-known/lnurlp/${user}`;
20
+ const metaResp = await fetch(metaUrl);
21
+ if (!metaResp.ok)
22
+ throw new Error(`LNURL fetch failed: ${metaResp.status} from ${metaUrl}`);
23
+ const meta = await metaResp.json();
24
+ if (meta.tag !== 'payRequest')
25
+ throw new Error(`Not a LNURL-pay endpoint (tag: ${meta.tag})`);
26
+ const amountMsats = amountSats * 1000;
27
+ if (amountMsats < meta.minSendable)
28
+ throw new Error(`Amount ${amountSats} sats below min ${meta.minSendable / 1000} sats`);
29
+ if (amountMsats > meta.maxSendable)
30
+ throw new Error(`Amount ${amountSats} sats above max ${meta.maxSendable / 1000} sats`);
31
+ // Step 2: Request invoice from callback
32
+ const sep = meta.callback.includes('?') ? '&' : '?';
33
+ const invoiceUrl = `${meta.callback}${sep}amount=${amountMsats}`;
34
+ const invoiceResp = await fetch(invoiceUrl);
35
+ if (!invoiceResp.ok)
36
+ throw new Error(`Invoice request failed: ${invoiceResp.status}`);
37
+ const invoiceData = await invoiceResp.json();
38
+ if (!invoiceData.pr)
39
+ throw new Error(`No invoice returned: ${invoiceData.reason || 'unknown error'}`);
40
+ return invoiceData.pr;
41
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "2020117-agent",
3
- "version": "0.6.2",
3
+ "version": "0.6.4",
4
4
  "description": "2020117 agent runtime — Nostr-native relay subscription + Hyperswarm P2P + Lightning payments",
5
5
  "type": "module",
6
6
  "bin": {
@@ -18,7 +18,7 @@
18
18
  "exports": {
19
19
  "./processor": "./dist/processor.js",
20
20
  "./swarm": "./dist/swarm.js",
21
- "./lightning": "./dist/clink.js",
21
+ "./lightning": "./dist/lnurl.js",
22
22
  "./nostr": "./dist/nostr.js",
23
23
  "./nwc": "./dist/nwc.js"
24
24
  },