@thecryptodonkey/toll-booth 3.5.0 → 3.6.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.
@@ -0,0 +1,24 @@
1
+ import type { Proof } from '@cashu/cashu-ts';
2
+ export type MeltResult = {
3
+ paid: true;
4
+ amountSats: number;
5
+ preimage?: string;
6
+ } | {
7
+ paid: false;
8
+ error: string;
9
+ };
10
+ /**
11
+ * Melts Cashu proofs to pay a Lightning invoice on the operator's node.
12
+ * Handles the full flow: invoice creation → melt quote → coin selection → melt.
13
+ * Discards change proofs (fee overpayment donated to mint).
14
+ *
15
+ * @param opts.mintUrl - The mint that issued the proofs
16
+ * @param opts.proofs - Server-side proofs from wallet.receive()
17
+ * @param opts.createInvoice - Callback to create a BOLT11 invoice on the operator's node
18
+ */
19
+ export declare function meltToLightning(opts: {
20
+ mintUrl: string;
21
+ proofs: Proof[];
22
+ createInvoice: (amountSats: number) => Promise<string>;
23
+ }): Promise<MeltResult>;
24
+ //# sourceMappingURL=melt-to-lightning.d.ts.map
@@ -0,0 +1,43 @@
1
+ import { Wallet } from '@cashu/cashu-ts';
2
+ /**
3
+ * Melts Cashu proofs to pay a Lightning invoice on the operator's node.
4
+ * Handles the full flow: invoice creation → melt quote → coin selection → melt.
5
+ * Discards change proofs (fee overpayment donated to mint).
6
+ *
7
+ * @param opts.mintUrl - The mint that issued the proofs
8
+ * @param opts.proofs - Server-side proofs from wallet.receive()
9
+ * @param opts.createInvoice - Callback to create a BOLT11 invoice on the operator's node
10
+ */
11
+ export async function meltToLightning(opts) {
12
+ const { mintUrl, proofs, createInvoice } = opts;
13
+ const totalSats = proofs.reduce((sum, p) => sum + p.amount, 0);
14
+ if (totalSats <= 0) {
15
+ return { paid: false, error: 'No proofs to melt' };
16
+ }
17
+ const wallet = new Wallet(mintUrl, { unit: 'sat' });
18
+ // Create invoice for the full proof amount
19
+ const invoice = await createInvoice(totalSats);
20
+ // Get melt quote to learn fee_reserve
21
+ const meltQuote = await wallet.createMeltQuoteBolt11(invoice);
22
+ const needed = meltQuote.amount + meltQuote.fee_reserve;
23
+ if (needed > totalSats) {
24
+ return {
25
+ paid: false,
26
+ error: `Proofs insufficient for fees (have ${totalSats}, need ${needed} including ${meltQuote.fee_reserve} fee reserve)`,
27
+ };
28
+ }
29
+ // Coin selection
30
+ const { send } = await wallet.send(needed, proofs, { includeFees: true });
31
+ // Melt — pay the Lightning invoice via the mint
32
+ const meltResponse = await wallet.meltProofsBolt11(meltQuote, send);
33
+ if (meltResponse.quote.state === 'PAID') {
34
+ // Discard change proofs (keep + change) — bearer instruments not retained
35
+ return {
36
+ paid: true,
37
+ amountSats: meltQuote.amount,
38
+ preimage: meltResponse.quote.payment_preimage ?? undefined,
39
+ };
40
+ }
41
+ return { paid: false, error: `Melt state: ${meltResponse.quote.state}` };
42
+ }
43
+ //# sourceMappingURL=melt-to-lightning.js.map
@@ -91,6 +91,18 @@ export function createXCashuRail(config, storage) {
91
91
  if (creditedAmount <= 0) {
92
92
  return FAIL;
93
93
  }
94
+ // Fire onProofsReceived callback (non-blocking, fire-and-forget)
95
+ if (config.onProofsReceived) {
96
+ try {
97
+ const cbResult = config.onProofsReceived(receivedProofs, tokenMint, creditedAmount);
98
+ if (cbResult && typeof cbResult.catch === 'function') {
99
+ cbResult.catch(() => { });
100
+ }
101
+ }
102
+ catch {
103
+ // Callback errors silently discarded — never block the payment flow
104
+ }
105
+ }
94
106
  // Generate payment ID and settlement secret
95
107
  const paymentId = randomBytes(32).toString('hex');
96
108
  const settlementSecret = randomBytes(32).toString('hex');
package/dist/index.d.ts CHANGED
@@ -29,6 +29,8 @@ export type { X402RailConfig, X402Facilitator, X402Payment, X402VerifyResult } f
29
29
  export { DEFAULT_USDC_ASSETS } from './core/x402-types.js';
30
30
  export { createXCashuRail } from './core/xcashu-rail.js';
31
31
  export type { XCashuConfig } from './types.js';
32
+ export { meltToLightning } from './core/melt-to-lightning.js';
33
+ export type { MeltResult } from './core/melt-to-lightning.js';
32
34
  export { mintMacaroon, verifyMacaroon, parseCaveats } from './macaroon.js';
33
35
  export type { VerifyContext, VerifyResult } from './macaroon.js';
34
36
  export { FreeTier, CreditFreeTier } from './free-tier.js';
package/dist/index.js CHANGED
@@ -18,6 +18,7 @@ export { createL402Rail } from './core/l402-rail.js';
18
18
  export { createX402Rail } from './core/x402-rail.js';
19
19
  export { DEFAULT_USDC_ASSETS } from './core/x402-types.js';
20
20
  export { createXCashuRail } from './core/xcashu-rail.js';
21
+ export { meltToLightning } from './core/melt-to-lightning.js';
21
22
  // Utilities
22
23
  export { mintMacaroon, verifyMacaroon, parseCaveats } from './macaroon.js';
23
24
  export { FreeTier, CreditFreeTier } from './free-tier.js';
package/dist/types.d.ts CHANGED
@@ -43,6 +43,7 @@ export interface LightningBackend {
43
43
  */
44
44
  checkInvoice(paymentHash: string): Promise<InvoiceStatus>;
45
45
  }
46
+ import type { Proof } from '@cashu/cashu-ts';
46
47
  import type { Currency, PricingEntry } from './core/payment-rail.js';
47
48
  import type { X402RailConfig } from './core/x402-types.js';
48
49
  /**
@@ -81,6 +82,12 @@ export interface XCashuConfig {
81
82
  mints: string[];
82
83
  /** Currency unit, default 'sat' */
83
84
  unit?: Currency;
85
+ /**
86
+ * Called after successful token swap with the server-side proofs.
87
+ * Fire-and-forget — the rail does NOT await this callback.
88
+ * Use for melting, persisting, or forwarding received ecash.
89
+ */
90
+ onProofsReceived?: (proofs: Proof[], mintUrl: string, amount: number) => void | Promise<void>;
84
91
  }
85
92
  /**
86
93
  * Configuration for a toll-booth instance.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thecryptodonkey/toll-booth",
3
- "version": "3.5.0",
3
+ "version": "3.6.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",