From 75338a275fdcbaeb06c24e4d5dd36a361571a4ae Mon Sep 17 00:00:00 2001 From: amackillop Date: Mon, 9 Mar 2026 10:20:48 -0700 Subject: [PATCH 1/2] Surface outbound payment events via next_event() Previously, PaymentSuccessful events from LDK were silently ACKed and discarded by next_event()'s catch-all arm. This meant callers using the event-polling model (as opposed to the blocking wait_for_payment_outcome path) could never learn when an outbound payment completed or obtain its preimage. This is a prerequisite for making agent-wallet payments non-blocking: instead of calling payWhileRunning with a 30-second timeout that blocks the Node.js thread and risks losing the preimage on timeout, the agent-wallet will fire-and-forget the payment and pick up the result through the event loop. Add a Sent variant (discriminant 3) to PaymentEventType and map Event::PaymentSuccessful to it in next_event(), carrying the payment_id and preimage. Also extend PaymentEvent with payment_id and preimage fields, and expose the previously-discarded payment_id on PaymentFailed events so callers can correlate failures to specific outbound payments. All new fields are Option and set to None on Claimable/Received events, so this is backwards-compatible for existing consumers that only match on the first three variants. --- src/lib.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 541a795..be6d4b1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -307,6 +307,10 @@ pub struct PaymentEvent { pub amount_msat: Option, pub reason: Option, pub payer_note: Option, + /// Opaque payment identifier. Present for Sent and Failed (outbound) events. + pub payment_id: Option, + /// Payment preimage (proof of payment). Present for Sent events. + pub preimage: Option, } #[napi] @@ -314,6 +318,7 @@ pub enum PaymentEventType { Claimable, Received, Failed, + Sent, } #[napi(object)] @@ -463,6 +468,8 @@ impl MdkNode { amount_msat: Some(*claimable_amount_msat as i64), reason: None, payer_note: None, + payment_id: None, + preimage: None, }), Event::PaymentReceived { payment_id, @@ -490,9 +497,12 @@ impl MdkNode { amount_msat: Some(*amount_msat as i64), reason: None, payer_note, + payment_id: None, + preimage: None, }) } Event::PaymentFailed { + payment_id: event_pid, payment_hash, reason, .. @@ -502,6 +512,22 @@ impl MdkNode { amount_msat: None, reason: reason.map(|r| format!("{r:?}")), payer_note: None, + payment_id: event_pid.map(|id| bytes_to_hex(&id.0)), + preimage: None, + }), + Event::PaymentSuccessful { + payment_id: event_pid, + payment_hash, + payment_preimage, + .. + } => Some(PaymentEvent { + event_type: PaymentEventType::Sent, + payment_hash: bytes_to_hex(&payment_hash.0), + amount_msat: None, + reason: None, + payer_note: None, + payment_id: event_pid.map(|id| bytes_to_hex(&id.0)), + preimage: payment_preimage.map(|p| bytes_to_hex(&p.0)), }), _ => None, }; From fcc8319bc4602a52deab0b0bae63c2ec7b4f0583 Mon Sep 17 00:00:00 2001 From: amackillop Date: Mon, 9 Mar 2026 12:21:12 -0700 Subject: [PATCH 2/2] Regenerate TypeScript bindings for payment events The previous commit added Sent to PaymentEventType and payment_id/preimage to PaymentEvent in Rust, but the checked-in index.d.ts was not regenerated. TypeScript consumers would see a stale API surface and could not type-check handlers for outbound payment events. --- index.d.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/index.d.ts b/index.d.ts index 795418e..251dc64 100644 --- a/index.d.ts +++ b/index.d.ts @@ -53,11 +53,16 @@ export interface PaymentEvent { amountMsat?: number reason?: string payerNote?: string + /** Opaque payment identifier. Present for Sent and Failed (outbound) events. */ + paymentId?: string + /** Payment preimage (proof of payment). Present for Sent events. */ + preimage?: string } export const enum PaymentEventType { Claimable = 0, Received = 1, Failed = 2, + Sent = 3 } export interface NodeChannel { channelId: string