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 +18 -3
- package/dist/lnurl.d.ts +14 -0
- package/dist/lnurl.js +41 -0
- package/package.json +2 -2
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 './
|
|
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)
|
|
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;
|
package/dist/lnurl.d.ts
ADDED
|
@@ -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.
|
|
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/
|
|
21
|
+
"./lightning": "./dist/lnurl.js",
|
|
22
22
|
"./nostr": "./dist/nostr.js",
|
|
23
23
|
"./nwc": "./dist/nwc.js"
|
|
24
24
|
},
|