@thecryptodonkey/toll-booth 1.4.0 → 2.0.0
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 -4
- package/dist/backends/nwc.d.ts +22 -0
- package/dist/backends/nwc.d.ts.map +1 -0
- package/dist/backends/nwc.js +65 -0
- package/dist/backends/nwc.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/llms.txt +2 -2
- package/package.json +6 -8
- package/dist/backends/alby.d.ts +0 -25
- package/dist/backends/alby.d.ts.map +0 -1
- package/dist/backends/alby.js +0 -137
- package/dist/backends/alby.js.map +0 -1
package/README.md
CHANGED
|
@@ -109,8 +109,8 @@ curl -H "Authorization: L402 <macaroon>:<preimage>" https://jokes.trotters.dev/a
|
|
|
109
109
|
## Features
|
|
110
110
|
|
|
111
111
|
- **L402 protocol** - industry-standard HTTP 402 payment flow with macaroon credentials
|
|
112
|
-
- **Multiple Lightning backends** - Phoenixd, LND, CLN, LNbits,
|
|
113
|
-
- **Alternative payment methods** -
|
|
112
|
+
- **Multiple Lightning backends** - Phoenixd, LND, CLN, LNbits, NWC (any Nostr Wallet Connect wallet)
|
|
113
|
+
- **Alternative payment methods** - Cashu ecash tokens
|
|
114
114
|
- **Cashu-only mode** - no Lightning node required; ideal for serverless and edge deployments
|
|
115
115
|
- **Credit system** - pre-paid balance with volume discount tiers
|
|
116
116
|
- **Free tier** - configurable daily allowance per IP
|
|
@@ -249,7 +249,7 @@ import { phoenixdBackend } from '@thecryptodonkey/toll-booth/backends/phoenixd'
|
|
|
249
249
|
import { lndBackend } from '@thecryptodonkey/toll-booth/backends/lnd'
|
|
250
250
|
import { clnBackend } from '@thecryptodonkey/toll-booth/backends/cln'
|
|
251
251
|
import { lnbitsBackend } from '@thecryptodonkey/toll-booth/backends/lnbits'
|
|
252
|
-
import {
|
|
252
|
+
import { nwcBackend } from '@thecryptodonkey/toll-booth/backends/nwc'
|
|
253
253
|
```
|
|
254
254
|
|
|
255
255
|
Each backend implements the `LightningBackend` interface (`createInvoice` + `checkInvoice`).
|
|
@@ -260,7 +260,7 @@ Each backend implements the `LightningBackend` interface (`createInvoice` + `che
|
|
|
260
260
|
| LND | Stable | Industry standard |
|
|
261
261
|
| CLN | Stable | Core Lightning REST API |
|
|
262
262
|
| LNbits | Stable | Any LNbits instance - self-hosted or hosted |
|
|
263
|
-
|
|
|
263
|
+
| NWC | Stable | Any Nostr Wallet Connect wallet (Alby Hub, Mutiny, Umbrel, Phoenix, etc.) — E2E encrypted via NIP-44 |
|
|
264
264
|
|
|
265
265
|
---
|
|
266
266
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { LightningBackend } from '../types.js';
|
|
2
|
+
export interface NwcConfig {
|
|
3
|
+
/** NWC connection URI: nostr+walletconnect://pubkey?relay=wss://...&secret=... */
|
|
4
|
+
nwcUrl: string;
|
|
5
|
+
/** Reply timeout in ms (default: 60000) */
|
|
6
|
+
timeout?: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Lightning backend adapter for Nostr Wallet Connect (NIP-47).
|
|
10
|
+
*
|
|
11
|
+
* Works with any NWC-compatible wallet (Alby Hub, Mutiny, Umbrel,
|
|
12
|
+
* Phoenix, and others). Communication is end-to-end encrypted over
|
|
13
|
+
* Nostr relays using NIP-44 (or NIP-04 for older wallets).
|
|
14
|
+
*
|
|
15
|
+
* The `nostr-core` package is imported dynamically so it only needs
|
|
16
|
+
* to be installed when this backend is actually used.
|
|
17
|
+
*
|
|
18
|
+
* @see https://nwc.dev/
|
|
19
|
+
* @see https://github.com/nostr-protocol/nips/blob/master/47.md
|
|
20
|
+
*/
|
|
21
|
+
export declare function nwcBackend(config: NwcConfig): LightningBackend;
|
|
22
|
+
//# sourceMappingURL=nwc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nwc.d.ts","sourceRoot":"","sources":["../../src/backends/nwc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAA0B,MAAM,aAAa,CAAA;AAE3E,MAAM,WAAW,SAAS;IACxB,kFAAkF;IAClF,MAAM,EAAE,MAAM,CAAA;IACd,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,gBAAgB,CAwD9D"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightning backend adapter for Nostr Wallet Connect (NIP-47).
|
|
3
|
+
*
|
|
4
|
+
* Works with any NWC-compatible wallet (Alby Hub, Mutiny, Umbrel,
|
|
5
|
+
* Phoenix, and others). Communication is end-to-end encrypted over
|
|
6
|
+
* Nostr relays using NIP-44 (or NIP-04 for older wallets).
|
|
7
|
+
*
|
|
8
|
+
* The `nostr-core` package is imported dynamically so it only needs
|
|
9
|
+
* to be installed when this backend is actually used.
|
|
10
|
+
*
|
|
11
|
+
* @see https://nwc.dev/
|
|
12
|
+
* @see https://github.com/nostr-protocol/nips/blob/master/47.md
|
|
13
|
+
*/
|
|
14
|
+
export function nwcBackend(config) {
|
|
15
|
+
const { nwcUrl, timeout } = config;
|
|
16
|
+
// Validate the connection string eagerly so config errors surface at startup
|
|
17
|
+
if (!nwcUrl || !nwcUrl.startsWith('nostr+walletconnect://')) {
|
|
18
|
+
throw new Error('NWC URL must start with nostr+walletconnect://');
|
|
19
|
+
}
|
|
20
|
+
// Lazy-initialised client — connects on first use
|
|
21
|
+
let clientPromise;
|
|
22
|
+
async function getClient() {
|
|
23
|
+
if (!clientPromise) {
|
|
24
|
+
clientPromise = (async () => {
|
|
25
|
+
const { NWC } = await import('nostr-core');
|
|
26
|
+
const nwc = new NWC(nwcUrl);
|
|
27
|
+
if (timeout !== undefined) {
|
|
28
|
+
nwc.replyTimeout = timeout;
|
|
29
|
+
}
|
|
30
|
+
await nwc.connect();
|
|
31
|
+
return nwc;
|
|
32
|
+
})();
|
|
33
|
+
}
|
|
34
|
+
return clientPromise;
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
async createInvoice(amountSats, memo) {
|
|
38
|
+
const nwc = await getClient();
|
|
39
|
+
const tx = await nwc.makeInvoice({
|
|
40
|
+
amount: amountSats * 1000, // NWC uses millisatoshis
|
|
41
|
+
description: memo,
|
|
42
|
+
});
|
|
43
|
+
if (!tx.invoice || !tx.payment_hash) {
|
|
44
|
+
throw new Error('NWC response missing invoice or payment_hash');
|
|
45
|
+
}
|
|
46
|
+
return { bolt11: tx.invoice, paymentHash: tx.payment_hash };
|
|
47
|
+
},
|
|
48
|
+
async checkInvoice(paymentHash) {
|
|
49
|
+
const nwc = await getClient();
|
|
50
|
+
try {
|
|
51
|
+
const tx = await nwc.lookupInvoice({ payment_hash: paymentHash });
|
|
52
|
+
const paid = tx.state === 'settled';
|
|
53
|
+
return {
|
|
54
|
+
paid,
|
|
55
|
+
preimage: paid ? tx.preimage : undefined,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// NOT_FOUND or other errors — treat as unpaid
|
|
60
|
+
return { paid: false };
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=nwc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nwc.js","sourceRoot":"","sources":["../../src/backends/nwc.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,UAAU,CAAC,MAAiB;IAC1C,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAA;IAElC,6EAA6E;IAC7E,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,wBAAwB,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAA;IACnE,CAAC;IAED,kDAAkD;IAClD,IAAI,aAAiF,CAAA;IAErF,KAAK,UAAU,SAAS;QACtB,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,aAAa,GAAG,CAAC,KAAK,IAAI,EAAE;gBAC1B,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAA;gBAC1C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAA;gBAC3B,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;oBAC1B,GAAG,CAAC,YAAY,GAAG,OAAO,CAAA;gBAC5B,CAAC;gBACD,MAAM,GAAG,CAAC,OAAO,EAAE,CAAA;gBACnB,OAAO,GAAG,CAAA;YACZ,CAAC,CAAC,EAAE,CAAA;QACN,CAAC;QACD,OAAO,aAAa,CAAA;IACtB,CAAC;IAED,OAAO;QACL,KAAK,CAAC,aAAa,CAAC,UAAkB,EAAE,IAAa;YACnD,MAAM,GAAG,GAAG,MAAM,SAAS,EAAE,CAAA;YAC7B,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,WAAW,CAAC;gBAC/B,MAAM,EAAE,UAAU,GAAG,IAAI,EAAE,yBAAyB;gBACpD,WAAW,EAAE,IAAI;aAClB,CAAC,CAAA;YAEF,IAAI,CAAC,EAAE,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC;gBACpC,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAA;YACjE,CAAC;YAED,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC,YAAY,EAAE,CAAA;QAC7D,CAAC;QAED,KAAK,CAAC,YAAY,CAAC,WAAmB;YACpC,MAAM,GAAG,GAAG,MAAM,SAAS,EAAE,CAAA;YAC7B,IAAI,CAAC;gBACH,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,aAAa,CAAC,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAA;gBACjE,MAAM,IAAI,GAAG,EAAE,CAAC,KAAK,KAAK,SAAS,CAAA;gBACnC,OAAO;oBACL,IAAI;oBACJ,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;iBACzC,CAAA;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,8CAA8C;gBAC9C,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;YACxB,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -41,8 +41,8 @@ export { clnBackend } from './backends/cln.js';
|
|
|
41
41
|
export type { ClnConfig } from './backends/cln.js';
|
|
42
42
|
export { lnbitsBackend } from './backends/lnbits.js';
|
|
43
43
|
export type { LNbitsConfig } from './backends/lnbits.js';
|
|
44
|
-
export {
|
|
45
|
-
export type {
|
|
44
|
+
export { nwcBackend } from './backends/nwc.js';
|
|
45
|
+
export type { NwcConfig } from './backends/nwc.js';
|
|
46
46
|
export type { LightningBackend, Invoice, InvoiceStatus, PricingTable, BoothConfig, CreditTier, PaymentEvent, RequestEvent, ChallengeEvent, EventHandler, } from './types.js';
|
|
47
47
|
export type { BoothStats } from './stats.js';
|
|
48
48
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -27,5 +27,5 @@ export { phoenixdBackend } from './backends/phoenixd.js';
|
|
|
27
27
|
export { lndBackend } from './backends/lnd.js';
|
|
28
28
|
export { clnBackend } from './backends/cln.js';
|
|
29
29
|
export { lnbitsBackend } from './backends/lnbits.js';
|
|
30
|
-
export {
|
|
30
|
+
export { nwcBackend } from './backends/nwc.js';
|
|
31
31
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,eAAe;AAEf,yBAAyB;AACzB,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAGlC,4BAA4B;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAItD,gBAAgB;AAChB,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAE9D,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AAEvF,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEhD,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAK3E,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD,WAAW;AACX,OAAO,EAAE,uBAAuB,EAAE,iCAAiC,EAAE,iCAAiC,EAAE,uBAAuB,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAA;AAEzL,OAAO,EAAE,2BAA2B,EAAE,qCAAqC,EAAE,qCAAqC,EAAE,2BAA2B,EAAE,6BAA6B,EAAE,MAAM,4BAA4B,CAAA;AAOlN,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACjG,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAE1D,YAAY;AACZ,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAE1E,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEzD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAEtE,mFAAmF;AACnF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAExD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEpD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,eAAe;AAEf,yBAAyB;AACzB,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAGlC,4BAA4B;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAItD,gBAAgB;AAChB,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAE9D,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AAEvF,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEhD,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAK3E,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD,WAAW;AACX,OAAO,EAAE,uBAAuB,EAAE,iCAAiC,EAAE,iCAAiC,EAAE,uBAAuB,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAA;AAEzL,OAAO,EAAE,2BAA2B,EAAE,qCAAqC,EAAE,qCAAqC,EAAE,2BAA2B,EAAE,6BAA6B,EAAE,MAAM,4BAA4B,CAAA;AAOlN,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACjG,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAE1D,YAAY;AACZ,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAE1E,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEzD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAEtE,mFAAmF;AACnF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAExD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEpD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA"}
|
package/llms.txt
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> toll-booth lets AI agents discover, pay for, and consume any HTTP API using Lightning, Cashu, or NWC - no accounts, no API keys, no human in the loop. It's L402 payment middleware that embeds in your Node.js app as middleware, supporting Express 5, Deno, Bun, and Cloudflare Workers.
|
|
4
4
|
|
|
5
|
-
toll-booth embeds in your existing Node.js application as middleware (not a separate proxy). It supports Express 5, Deno, Bun, and Cloudflare Workers. Five Lightning backends are supported (Phoenixd, LND, Core Lightning, LNbits,
|
|
5
|
+
toll-booth embeds in your existing Node.js application as middleware (not a separate proxy). It supports Express 5, Deno, Bun, and Cloudflare Workers. Five Lightning backends are supported (Phoenixd, LND, Core Lightning, LNbits, NWC), or you can run in Cashu-only mode with no Lightning node at all — ideal for serverless and edge deployments.
|
|
6
6
|
|
|
7
7
|
The closest alternative is Aperture (Lightning Labs), a Go reverse proxy that requires LND. toll-booth is TypeScript middleware that works with any Lightning backend, runs serverless, and supports Cashu ecash payments.
|
|
8
8
|
|
|
@@ -73,7 +73,7 @@ Subpath imports for tree-shaking:
|
|
|
73
73
|
- `@thecryptodonkey/toll-booth/backends/lnd` — LND backend
|
|
74
74
|
- `@thecryptodonkey/toll-booth/backends/cln` — Core Lightning backend
|
|
75
75
|
- `@thecryptodonkey/toll-booth/backends/lnbits` — LNbits backend
|
|
76
|
-
- `@thecryptodonkey/toll-booth/backends/
|
|
76
|
+
- `@thecryptodonkey/toll-booth/backends/nwc` — Nostr Wallet Connect (NIP-47) backend
|
|
77
77
|
- `@thecryptodonkey/toll-booth/storage/sqlite` — SQLite storage (default)
|
|
78
78
|
- `@thecryptodonkey/toll-booth/storage/memory` — in-memory storage (testing)
|
|
79
79
|
- `@thecryptodonkey/toll-booth/adapters/express` — Express middleware factory
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thecryptodonkey/toll-booth",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Monetise any API with HTTP 402 payments. Payment-rail agnostic middleware for Express, Hono, Deno, Bun, and Workers.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -55,9 +55,9 @@
|
|
|
55
55
|
"import": "./dist/backends/cln.js",
|
|
56
56
|
"types": "./dist/backends/cln.d.ts"
|
|
57
57
|
},
|
|
58
|
-
"./backends/
|
|
59
|
-
"import": "./dist/backends/
|
|
60
|
-
"types": "./dist/backends/
|
|
58
|
+
"./backends/nwc": {
|
|
59
|
+
"import": "./dist/backends/nwc.js",
|
|
60
|
+
"types": "./dist/backends/nwc.d.ts"
|
|
61
61
|
},
|
|
62
62
|
"./backends/lnbits": {
|
|
63
63
|
"import": "./dist/backends/lnbits.js",
|
|
@@ -101,6 +101,7 @@
|
|
|
101
101
|
"dependencies": {
|
|
102
102
|
"better-sqlite3": "^11.8.0",
|
|
103
103
|
"macaroon": "^3.0.4",
|
|
104
|
+
"nostr-core": "^0.4.0",
|
|
104
105
|
"qrcode": "^1.5.4"
|
|
105
106
|
},
|
|
106
107
|
"peerDependencies": {
|
|
@@ -124,7 +125,6 @@
|
|
|
124
125
|
"@types/better-sqlite3": "^7.6.0",
|
|
125
126
|
"@types/express": "^5.0.6",
|
|
126
127
|
"@types/qrcode": "^1.5.6",
|
|
127
|
-
"@types/ws": "^8.18.1",
|
|
128
128
|
"express": "^5.2.1",
|
|
129
129
|
"hono": "^4.12.7",
|
|
130
130
|
"patch-package": "^8.0.1",
|
|
@@ -133,7 +133,5 @@
|
|
|
133
133
|
"typescript": "^5.7.0",
|
|
134
134
|
"vitest": "^3.0.0"
|
|
135
135
|
},
|
|
136
|
-
"optionalDependencies": {
|
|
137
|
-
"ws": "^8.19.0"
|
|
138
|
-
}
|
|
136
|
+
"optionalDependencies": {}
|
|
139
137
|
}
|
package/dist/backends/alby.d.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import type { LightningBackend } from '../types.js';
|
|
2
|
-
export interface AlbyConfig {
|
|
3
|
-
/** NWC connection URI: nostr+walletconnect://pubkey?relay=wss://...&secret=... */
|
|
4
|
-
nwcUrl: string;
|
|
5
|
-
/** Request timeout in ms (default: 30000) */
|
|
6
|
-
timeout?: number;
|
|
7
|
-
/**
|
|
8
|
-
* Opt into the current insecure JSON-over-relay transport.
|
|
9
|
-
* This exists only for local testing and trusted relay experiments.
|
|
10
|
-
*/
|
|
11
|
-
allowInsecureRelay?: boolean;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Lightning backend adapter for Alby / Nostr Wallet Connect (NWC).
|
|
15
|
-
*
|
|
16
|
-
* This transport is intentionally disabled by default because it sends
|
|
17
|
-
* unsigned, unencrypted JSON directly to the relay and therefore cannot
|
|
18
|
-
* authenticate responses. Pass `allowInsecureRelay: true` only for local
|
|
19
|
-
* testing or a fully trusted relay shim.
|
|
20
|
-
*
|
|
21
|
-
* The `ws` package is imported dynamically so it only needs to be
|
|
22
|
-
* installed when this backend is actually used.
|
|
23
|
-
*/
|
|
24
|
-
export declare function albyBackend(config: AlbyConfig): LightningBackend;
|
|
25
|
-
//# sourceMappingURL=alby.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"alby.d.ts","sourceRoot":"","sources":["../../src/backends/alby.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAA0B,MAAM,aAAa,CAAA;AAE3E,MAAM,WAAW,UAAU;IACzB,kFAAkF;IAClF,MAAM,EAAE,MAAM,CAAA;IACd,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B;AAkCD;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,gBAAgB,CAmEhE"}
|
package/dist/backends/alby.js
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
function parseNwcUrl(nwcUrl) {
|
|
2
|
-
// Replace the custom scheme so URL parser can handle it
|
|
3
|
-
const url = new URL(nwcUrl.replace('nostr+walletconnect://', 'https://'));
|
|
4
|
-
const pubkey = url.hostname;
|
|
5
|
-
const relay = url.searchParams.get('relay');
|
|
6
|
-
const secret = url.searchParams.get('secret');
|
|
7
|
-
if (!relay)
|
|
8
|
-
throw new Error('NWC URL missing required "relay" parameter');
|
|
9
|
-
if (!secret)
|
|
10
|
-
throw new Error('NWC URL missing required "secret" parameter');
|
|
11
|
-
return { pubkey, relay, secret };
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Lightning backend adapter for Alby / Nostr Wallet Connect (NWC).
|
|
15
|
-
*
|
|
16
|
-
* This transport is intentionally disabled by default because it sends
|
|
17
|
-
* unsigned, unencrypted JSON directly to the relay and therefore cannot
|
|
18
|
-
* authenticate responses. Pass `allowInsecureRelay: true` only for local
|
|
19
|
-
* testing or a fully trusted relay shim.
|
|
20
|
-
*
|
|
21
|
-
* The `ws` package is imported dynamically so it only needs to be
|
|
22
|
-
* installed when this backend is actually used.
|
|
23
|
-
*/
|
|
24
|
-
export function albyBackend(config) {
|
|
25
|
-
if (!config.allowInsecureRelay) {
|
|
26
|
-
throw new Error('albyBackend is disabled by default because its JSON relay transport is unauthenticated; pass allowInsecureRelay: true only for local testing');
|
|
27
|
-
}
|
|
28
|
-
const params = parseNwcUrl(config.nwcUrl);
|
|
29
|
-
const timeoutMs = config.timeout ?? 30_000;
|
|
30
|
-
const MAX_CACHED_INVOICES = 10_000;
|
|
31
|
-
const invoiceMap = new Map();
|
|
32
|
-
return {
|
|
33
|
-
async createInvoice(amountSats, memo) {
|
|
34
|
-
const result = await sendNwcRequest(params, timeoutMs, 'make_invoice', {
|
|
35
|
-
amount: amountSats * 1000, // NWC uses millisats
|
|
36
|
-
description: memo,
|
|
37
|
-
});
|
|
38
|
-
const bolt11 = getStringField(result, 'invoice') ?? getStringField(result, 'bolt11');
|
|
39
|
-
const paymentHash = getStringField(result, 'payment_hash') ?? getStringField(result, 'paymentHash');
|
|
40
|
-
if (!bolt11 || !paymentHash) {
|
|
41
|
-
throw new Error('NWC response missing invoice or payment_hash');
|
|
42
|
-
}
|
|
43
|
-
// Evict oldest entries when cache is full (Map preserves insertion order)
|
|
44
|
-
if (invoiceMap.size >= MAX_CACHED_INVOICES) {
|
|
45
|
-
const oldest = invoiceMap.keys().next().value;
|
|
46
|
-
invoiceMap.delete(oldest);
|
|
47
|
-
}
|
|
48
|
-
invoiceMap.set(paymentHash, { bolt11, paid: false });
|
|
49
|
-
return { bolt11, paymentHash };
|
|
50
|
-
},
|
|
51
|
-
async checkInvoice(paymentHash) {
|
|
52
|
-
const entry = invoiceMap.get(paymentHash);
|
|
53
|
-
if (!entry)
|
|
54
|
-
return { paid: false };
|
|
55
|
-
if (entry.paid) {
|
|
56
|
-
return { paid: true, preimage: entry.preimage };
|
|
57
|
-
}
|
|
58
|
-
const result = await sendNwcRequest(params, timeoutMs, 'lookup_invoice', { payment_hash: paymentHash });
|
|
59
|
-
const lookupRecord = result;
|
|
60
|
-
const paid = isPaid(result);
|
|
61
|
-
const preimage = paid
|
|
62
|
-
? getStringField(lookupRecord, 'payment_preimage') ?? getStringField(lookupRecord, 'preimage')
|
|
63
|
-
: undefined;
|
|
64
|
-
const bolt11 = getStringField(lookupRecord, 'invoice') ?? getStringField(lookupRecord, 'bolt11') ?? entry.bolt11;
|
|
65
|
-
invoiceMap.set(paymentHash, { bolt11, paid, preimage });
|
|
66
|
-
return { paid, preimage };
|
|
67
|
-
},
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
async function sendNwcRequest(params, timeoutMs, method, requestParams) {
|
|
71
|
-
const { default: WebSocket } = await import('ws');
|
|
72
|
-
return new Promise((resolve, reject) => {
|
|
73
|
-
const ws = new WebSocket(params.relay);
|
|
74
|
-
let settled = false;
|
|
75
|
-
const cleanup = () => {
|
|
76
|
-
if (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING) {
|
|
77
|
-
ws.close();
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
const finish = (fn) => {
|
|
81
|
-
if (settled)
|
|
82
|
-
return;
|
|
83
|
-
settled = true;
|
|
84
|
-
clearTimeout(timer);
|
|
85
|
-
cleanup();
|
|
86
|
-
fn();
|
|
87
|
-
};
|
|
88
|
-
const timer = setTimeout(() => {
|
|
89
|
-
finish(() => reject(new Error(`NWC ${method} timed out`)));
|
|
90
|
-
}, timeoutMs);
|
|
91
|
-
ws.on('open', () => {
|
|
92
|
-
ws.send(JSON.stringify({
|
|
93
|
-
method,
|
|
94
|
-
params: requestParams,
|
|
95
|
-
}));
|
|
96
|
-
});
|
|
97
|
-
ws.on('message', (data) => {
|
|
98
|
-
finish(() => {
|
|
99
|
-
try {
|
|
100
|
-
const response = JSON.parse(data.toString());
|
|
101
|
-
const error = response.error;
|
|
102
|
-
if (error) {
|
|
103
|
-
reject(new Error(`NWC ${method} failed: ${formatError(error)}`));
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
resolve((response.result ?? response));
|
|
107
|
-
}
|
|
108
|
-
catch (err) {
|
|
109
|
-
reject(new Error(`Failed to parse NWC response: ${err}`));
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
ws.on('error', (err) => {
|
|
114
|
-
finish(() => reject(new Error(`NWC WebSocket error: ${err.message}`)));
|
|
115
|
-
});
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
function getStringField(record, key) {
|
|
119
|
-
const value = record[key];
|
|
120
|
-
return typeof value === 'string' && value.length > 0 ? value : undefined;
|
|
121
|
-
}
|
|
122
|
-
function isPaid(result) {
|
|
123
|
-
return result.paid === true ||
|
|
124
|
-
result.settled === true ||
|
|
125
|
-
result.state === 'paid' ||
|
|
126
|
-
result.state === 'settled' ||
|
|
127
|
-
result.settled_at !== undefined;
|
|
128
|
-
}
|
|
129
|
-
function formatError(error) {
|
|
130
|
-
if (typeof error === 'string')
|
|
131
|
-
return error;
|
|
132
|
-
if (error && typeof error === 'object' && 'message' in error && typeof error.message === 'string') {
|
|
133
|
-
return error.message;
|
|
134
|
-
}
|
|
135
|
-
return 'unknown error';
|
|
136
|
-
}
|
|
137
|
-
//# sourceMappingURL=alby.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"alby.js","sourceRoot":"","sources":["../../src/backends/alby.ts"],"names":[],"mappings":"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"}
|