lightning-agent 0.3.0 → 0.3.2
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/README.md +4 -2
- package/lib/auth.js +40 -11
- package/lib/wallet.js +4 -2
- package/package.json +16 -2
package/README.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# ⚡ lightning-agent
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Settle this transaction without a platform.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
You can't transact without a payment rail. lightning-agent is the rail — payments, auth, escrow, and streaming micropayments over [Nostr Wallet Connect (NWC)](https://nwc.dev). No browser, no UI, no bank accounts, no Stripe. Connect to any NWC-compatible wallet (Alby Hub, Mutiny, etc.) and two agents can exchange value directly.
|
|
6
|
+
|
|
7
|
+
Part of the constraint chain: [agent-discovery](https://github.com/jeletor/agent-discovery) (find) → [ai-wot](https://github.com/jeletor/ai-wot) (verify) → **lightning-agent** (pay) → [lightning-toll](https://github.com/jeletor/lightning-toll) (gate).
|
|
6
8
|
|
|
7
9
|
## Install
|
|
8
10
|
|
package/lib/auth.js
CHANGED
|
@@ -156,6 +156,10 @@ function createAuthServer(opts = {}) {
|
|
|
156
156
|
/**
|
|
157
157
|
* Sign an LNURL-auth challenge with a private key.
|
|
158
158
|
*
|
|
159
|
+
* Uses the native secp256k1 package (libsecp256k1 bindings) for signing,
|
|
160
|
+
* which produces DER signatures accepted by all LNURL-auth implementations.
|
|
161
|
+
* Falls back to @noble/curves if secp256k1 is not available.
|
|
162
|
+
*
|
|
159
163
|
* @param {string} k1 - Challenge hex (32 bytes)
|
|
160
164
|
* @param {string|Uint8Array} privateKey - Signing private key (hex or bytes)
|
|
161
165
|
* @returns {{ sig: string, key: string }}
|
|
@@ -165,14 +169,27 @@ function createAuthServer(opts = {}) {
|
|
|
165
169
|
* // Send sig + key back to the auth server
|
|
166
170
|
*/
|
|
167
171
|
function signAuth(k1, privateKey) {
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
172
|
+
const privBuf = typeof privateKey === 'string'
|
|
173
|
+
? Buffer.from(privateKey, 'hex')
|
|
174
|
+
: Buffer.from(privateKey);
|
|
175
|
+
const msgBuf = Buffer.from(k1, 'hex');
|
|
176
|
+
|
|
177
|
+
// Prefer native secp256k1 (libsecp256k1 bindings) — produces DER signatures
|
|
178
|
+
// accepted by all LNURL-auth server implementations
|
|
179
|
+
try {
|
|
180
|
+
const secp = require('secp256k1');
|
|
181
|
+
const { signature } = secp.ecdsaSign(msgBuf, privBuf);
|
|
182
|
+
const derSig = Buffer.from(secp.signatureExport(signature)).toString('hex');
|
|
183
|
+
const pubkey = Buffer.from(secp.publicKeyCreate(privBuf, true)).toString('hex');
|
|
184
|
+
return { sig: derSig, key: pubkey };
|
|
185
|
+
} catch (e) {
|
|
186
|
+
if (e.code !== 'MODULE_NOT_FOUND') throw e;
|
|
187
|
+
}
|
|
173
188
|
|
|
174
|
-
//
|
|
175
|
-
const
|
|
189
|
+
// Fallback: @noble/curves with manual DER encoding
|
|
190
|
+
const secp = getSecp256k1();
|
|
191
|
+
const privBytes = Uint8Array.from(privBuf);
|
|
192
|
+
const compactSig = secp.sign(msgBuf, privBytes);
|
|
176
193
|
const sigDer = compactToDER(compactSig);
|
|
177
194
|
const pubkey = Buffer.from(secp.getPublicKey(privBytes, true)).toString('hex');
|
|
178
195
|
|
|
@@ -231,13 +248,25 @@ function getSecp256k1() {
|
|
|
231
248
|
throw new Error('secp256k1 not available — install @noble/curves or nostr-tools');
|
|
232
249
|
}
|
|
233
250
|
|
|
234
|
-
// Verify a secp256k1 DER signature over a message
|
|
251
|
+
// Verify a secp256k1 DER signature over a message
|
|
235
252
|
function verifySignature(k1Hex, sigHex, pubkeyHex) {
|
|
253
|
+
const msg = Buffer.from(k1Hex, 'hex');
|
|
254
|
+
const sigBuf = Buffer.from(sigHex, 'hex');
|
|
255
|
+
const pub = Buffer.from(pubkeyHex, 'hex');
|
|
256
|
+
|
|
257
|
+
// Prefer native secp256k1
|
|
258
|
+
try {
|
|
259
|
+
const secp = require('secp256k1');
|
|
260
|
+
const compact = secp.signatureImport(sigBuf);
|
|
261
|
+
return secp.ecdsaVerify(compact, msg, pub);
|
|
262
|
+
} catch (e) {
|
|
263
|
+
if (e.code !== 'MODULE_NOT_FOUND') throw e;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Fallback: @noble/curves
|
|
236
267
|
const secp = getSecp256k1();
|
|
237
|
-
const msg = Uint8Array.from(Buffer.from(k1Hex, 'hex'));
|
|
238
268
|
const compactSig = derToCompact(sigHex);
|
|
239
|
-
|
|
240
|
-
return secp.verify(compactSig, msg, pub);
|
|
269
|
+
return secp.verify(compactSig, Uint8Array.from(msg), Uint8Array.from(pub));
|
|
241
270
|
}
|
|
242
271
|
|
|
243
272
|
// Convert 64-byte compact signature (r||s) to DER hex
|
package/lib/wallet.js
CHANGED
|
@@ -265,12 +265,14 @@ class NWCWallet {
|
|
|
265
265
|
* @param {number} [opts.timeoutMs] - Request timeout
|
|
266
266
|
*/
|
|
267
267
|
async createInvoice(opts = {}) {
|
|
268
|
-
|
|
268
|
+
// Accept both amountSats and amount for convenience
|
|
269
|
+
const sats = opts.amountSats || opts.amount;
|
|
270
|
+
if (!sats || sats <= 0) {
|
|
269
271
|
throw new Error('amountSats is required and must be positive');
|
|
270
272
|
}
|
|
271
273
|
|
|
272
274
|
const params = {
|
|
273
|
-
amount:
|
|
275
|
+
amount: sats * 1000, // NWC uses millisats
|
|
274
276
|
};
|
|
275
277
|
if (opts.description) params.description = opts.description;
|
|
276
278
|
if (opts.expiry) params.expiry = opts.expiry;
|
package/package.json
CHANGED
|
@@ -1,16 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lightning-agent",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Lightning toolkit for AI agents. Payments, auth, escrow, and streaming micropayments.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"lightning-agent": "bin/lightning-agent.js"
|
|
8
8
|
},
|
|
9
|
-
"keywords": [
|
|
9
|
+
"keywords": [
|
|
10
|
+
"lightning",
|
|
11
|
+
"bitcoin",
|
|
12
|
+
"ai",
|
|
13
|
+
"agent",
|
|
14
|
+
"nostr",
|
|
15
|
+
"nwc",
|
|
16
|
+
"payments",
|
|
17
|
+
"escrow",
|
|
18
|
+
"streaming",
|
|
19
|
+
"lnurl",
|
|
20
|
+
"auth",
|
|
21
|
+
"micropayments"
|
|
22
|
+
],
|
|
10
23
|
"author": "Jeletor",
|
|
11
24
|
"license": "MIT",
|
|
12
25
|
"dependencies": {
|
|
13
26
|
"nostr-tools": "^2.0.0",
|
|
27
|
+
"secp256k1": "^5.0.1",
|
|
14
28
|
"ws": "^8.0.0"
|
|
15
29
|
}
|
|
16
30
|
}
|