@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 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, Alby
113
- - **Alternative payment methods** - Nostr Wallet Connect (NWC) and Cashu ecash tokens
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 { albyBackend } from '@thecryptodonkey/toll-booth/backends/alby'
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
- | Alby (NWC) | Experimental | JSON relay transport is unauthenticated; only enable with `allowInsecureRelay: true` for local testing or a fully trusted relay |
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 { albyBackend } from './backends/alby.js';
45
- export type { AlbyConfig } from './backends/alby.js';
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
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAG3D,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAG9G,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,YAAY,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AACjE,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AACvF,YAAY,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAC3E,YAAY,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAG7D,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACxF,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAGnD,OAAO,EAAE,uBAAuB,EAAE,iCAAiC,EAAE,iCAAiC,EAAE,uBAAuB,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAA;AACzL,YAAY,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AACpE,OAAO,EAAE,2BAA2B,EAAE,qCAAqC,EAAE,qCAAqC,EAAE,2BAA2B,EAAE,6BAA6B,EAAE,MAAM,4BAA4B,CAAA;AAClN,YAAY,EAAE,kBAAkB,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAA;AAEjG,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAG5G,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAC9J,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACjG,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAC1G,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAG1D,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC1E,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAChE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AACzD,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAGtE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,YAAY,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,YAAY,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,YAAY,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,YAAY,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAGpD,YAAY,EACV,gBAAgB,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EACnE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,GACrE,MAAM,YAAY,CAAA;AACnB,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA"}
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 { albyBackend } from './backends/alby.js';
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,WAAW,EAAE,MAAM,oBAAoB,CAAA"}
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, Alby), or you can run in Cashu-only mode with no Lightning node at all — ideal for serverless and edge deployments.
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/alby` — Alby / NWC backend
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": "1.4.0",
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/alby": {
59
- "import": "./dist/backends/alby.js",
60
- "types": "./dist/backends/alby.d.ts"
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
  }
@@ -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"}
@@ -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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"}